2010-08-14 13 views
5

Sto lavorando a uno sviluppo XSL e ho bisogno di conoscere l'equivalente NOT IN in XPATH. Sto presentando XML e XSL nel formato più semplice che sarebbe comprensibile a tutti.Non equivalente in espressione 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> 

Nel XSLT sopra, sotto l'area commentato, ho bisogno di abbinare e visualizzare i clienti che di indirizzo non è esistente nel Indirizzo/Indirizzo nodo.

Si prega di aiutare a trovare un'espressione XPath che corrisponda ai clienti che NON sono nel set di nodi degli indirizzi. (Qualsiasi alternate potrebbe anche contribuire)

+0

Buona domanda (+1). Vedi la mia risposta per una soluzione XSLT efficiente, breve e semplice. :) –

risposta

7

In XPath 1.0:

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

Wow funziona bene. Grazie mille. – SaravananArumugam

+0

@Saravanands: Sei il benvenuto! –

+0

+1. Questa è una conoscenza fondamentale di XPath - sfortunatamente l'OP è felice che "funzioni" e probabilmente non approfondirebbe ulteriormente per capire cosa stia realmente succedendo ... :( –

4

Un'alternativa alla buona risposta da @Alejandro, che upvoted, è la seguente trasformazione, che utilizza chiavi e sarà più efficiente se il numero dei clienti esistenti è 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> 

quando tale trasformazione viene applicato sul documento XML fornito:

<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> 

The Wanted, risposta corretta viene prodotto:

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