A variable $rows has a list of node ids that key into some source XML.
<row>
<node id="d0113" />
<node id="d0237" />
<node id="d0321" />
</row>
<row>
<node id="c0278" />
<node id="d0137" />
<node id="e0021" />
</row>
What is a good way to test, before processing each <row>, whether any of nodes keyed to actually exist in a node-set $set?
All I’ve come up with is
<xsl:for-each select="row">
<xsl:variable name="test">
<xsl:for-each select="node">
<xsl:value-of select="boolean($set//*[generate-id()=current()/@id]) * 1"/>
</xsl:for-each>
</xsl:variable>
<xsl:if test="$test>0">
<!-- go ahead and process the row -->
</xsl:if>
</xsl:for-each>
This will in most cases return
false()so this whole method of “indexing” is incorrect.This is because the values of
generate-id()for any node in an XML document aren’t guaranteed to be the same from transformation to transformation.Even if in the provided XML document any
node/@idattribute was generated to have the value ofgenerate-id()on some particular node of the second document, nothing guarantees that in a consequent new transformationgenerate-id()on that same node will produce the same valu as the one that was used to generate the respectivenode/@id.Recommendation:
For such indexing use a more stable function of a node — one example of such function is the XPath expression that selects exactly that node.
If the document hasn’ been modified, that XPath expression is going always to select that node.
Update:
In a comment the OP maintains that the
node/@idattributes are both generated and used in the same transformation.In this case, this single XPath expression produces a boolen that indicates whether or not
$setcontains at least one node whosegenerate-id()is one of thenode/@idattributes of another document:In a
testattribute of a conditional instruction, just the argument toboolean()above can be used.Explanation:
The expression:
Selects all nodes in
$setwhose value ofgenerate-id()is equal to at least onesomeExpression/row/node/@idattribute’s value (someExpression here stands for the missing location steps about which we know nothing, since no XML document has been provided).By definition,
boolean($someNodeSet)is alwaystrue()if the node-set$someNodeSetcontains at least one node, and is false if$someNodeSetis the empty node-set.