I am working on an XSL development and I am in need of knowing the NOT IN equivalent in XPATH. I am presenting the XML and XSL in the simplest format which would be understandable to all.
<?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>
开发者_如何学Python <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>
In the above XSLT, under the commented area, i need to match and display the customers who's address is not existing in the Addresses/Address node.
Please help find an XPath expression that would match the Customers who are NOT IN the Addresses Node set. (Any alternate could also help)
In XPath 1.0:
/Message/Customers/Customer[not(@pin=/Message/Addresses/Address/@pin1)]
An alternative to the good answer by @Alejandro, which I upvoted, is the following transformation, which uses keys and will be more efficient if the number of existing customers is big:
<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>
when this transformation is applied on the provided XML document:
<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, correct answer is produced:
<Customer pin="06070">4</Customer>
<Customer pin="06072">5</Customer>
精彩评论