2010-08-14 22 views
5

Estoy trabajando en un desarrollo XSL y necesito conocer el equivalente NOT IN en XPATH. Estoy presentando el XML y el XSL en el formato más simple que sería comprensible para todos.No equivalente IN en la expresión XPath

<?xml-stylesheet type="text/xsl" href="XSL.xsl"?> 
<Message> 
    <Customers> 
     <Customer pin="06067">1</Customer> 
     <Customer pin="06068">2</Customer> 
     <Customer pin="06069">3</Customer> 
     <Customer pin="06070">4</Customer> 
     <Customer pin="06072">5</Customer> 
    </Customers> 
    <Addresses> 
     <Address pin1="06067">A</Address> 
     <Address pin1="06068">B</Address> 
     <Address pin1="06069">C</Address> 
    </Addresses> 
</Message> 

XSL

<xsl:template match="/Message"> 
    <html> 
     <body> 
      <h4>Existing Customers</h4> 
      <table> 
       <xsl:apply-templates select="//Customers/Customer[@pin = //Addresses/Address/@pin1]"></xsl:apply-templates> 
      </table> 

      <h4>New Customers</h4> 
      <table> 
       <!--This place need to be filled with new customers--> 
      </table> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="Customer" name="Customer"> 
    <xsl:variable name="pin" select="./@pin"></xsl:variable> 
    <tr> 
     <td> 
      <xsl:value-of select="."/> 
      <xsl:text> is in </xsl:text> 
      <xsl:value-of select="//Addresses/Address[@pin1=$pin]"/> 
     </td> 
    </tr> 
</xsl:template> 

En el XSLT anteriormente, en el área de comentarios, tenemos que asociar y mostrar los clientes que de dirección no es existente en el Direcciones/nodo de dirección.

Ayúdenos a encontrar una expresión XPath que coincida con los clientes que NO están en el conjunto de Nodo de direcciones. (Cualquier alternativa también podría ayudar)

+0

Buena pregunta (1). Vea mi respuesta para una solución XSLT corta, simple y eficiente. :) –

Respuesta

7

En XPath 1.0:

/Message/Customers/Customer[not(@pin=/Message/Addresses/Address/@pin1)] 
+0

Wow, funciona bien. Muchas gracias. – SaravananArumugam

+0

@Saravanandss: ¡Eres bienvenido! –

+0

+1. Este es el conocimiento fundamental de XPath: desafortunadamente, el OP está contento de que "funcione" y probablemente no profundice más para comprender lo que realmente está sucediendo ... :( –

4

Una alternativa a la buena respuesta por @Alejandro, que upvoted, es el siguiente transformación, que utiliza claves y habrá más eficiente si el número de clientes existentes es grande:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:key name="kexistingByPin" 
     match="Address" use="@pin1"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/"> 
    <xsl:apply-templates select= 
    "*/*/Customer[not(key('kexistingByPin', @pin))]"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica esta transformación en el documento XML proporcionado:

<Message> 
    <Customers> 
     <Customer pin="06067">1</Customer> 
     <Customer pin="06068">2</Customer> 
     <Customer pin="06069">3</Customer> 
     <Customer pin="06070">4</Customer> 
     <Customer pin="06072">5</Customer> 
    </Customers> 
    <Addresses> 
     <Address pin1="06067">A</Address> 
     <Address pin1="06068">B</Address> 
     <Address pin1="06069">C</Address> 
    </Addresses> 
</Message> 

la, respuesta correcta deseada se produce:

<Customer pin="06070">4</Customer> 
<Customer pin="06072">5</Customer> 
Cuestiones relacionadas