I have two variables that look like
<xsl:variable name="A">
<asset id="111">[...]</asset>
<asset id="222">[...]</asset>
</xsl:variable>
<xsl:variable name="B">
<asset id="333">[...]</asset>
<asset id="444">[...]</asset>
<asset id="111">[...]</asset>
<asset id="555">[...]</asset>
<asset id="999">[...]</asset>
</xsl:variable>
I wish to take each ID value of A and check to see if it is NOT found in B. If it is NOT found, copy the current node from A into the new variable.
<xsl:variable name="Final">
<xsl:for-each select="$A/asset">
<xsl:variable name="presentXML">
<xsl:copy-of select="."/>
</xsl:variable>
<xsl:variable name="presentID">
<xsl:value-of select="./@id"/>
</xsl:variable>
<xsl:for-each select="$B/asset">
<xsl:variable name="pastID">
<xsl:value-of select="./@id"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$presentID != $pastID">
<xsl:copy-of select="$presentXML"/>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise >
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
If the code above worked, only [...] would be added to variable Final. I cannot come up with a way to properly test in <xsl:when test="$presentID != $pastID"> to produce this result. I understand why that doesn't work properly, but can someone say how I could go about this?
XSLT is a functional language. There is no need to iterate. You can do simply:
<xsl:copy-of select="$A/asset[not(@id=$B/asset/@id)]"/>
(Provided your processor supports XSLT 2.0 or higher. Otherwise you will need to convert the variables to a node-set first.)
Do note that:
[not(@id=$B/asset/@id)]
is not the same thing as:
[@id!=$B/asset/@id]
The latter is true when there is at least one id
in $B
that is not equal to the current id
(and therefore it will be true for any id
from $A
, as long as there are at least two different id
s in $B
.