Reputation: 83
I am currently learning XSLT and a bit confused about an example I found in a book. To select all nodes, except a certain node, it says to use:
<xsl:apply-templates select="node()[not(self::CHILD_B)]" />
This works, but I was wondering why the self::
part is at all needed? Why does <xsl:apply-templates select="node()[not(CHILD_B)]" />
not work? After all <xsl:apply-templates select="CHILD_B" />
would work to select the element (without the self::
part), so why do we need the self::
part when excluding it?
Examples:
test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<CHILD_A>
Test A
</CHILD_A>
<CHILD_B>
This element should be ignored.
</CHILD_B>
<CHILD_C>
Test C
</CHILD_C>
</ROOT>
test.xsl:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="ROOT">
<xsl:apply-templates select="node()[not(self::CHILD_B)]" />
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Views: 684
Reputation: 167716
Inside the predicate, the context node is changed to whatever node was selected in the expression on the left side of the predicate so node()[not(CHILD_B)]
looks for any child node of the context node but then, inside the predicate to be evaluated, this child node is the context node so that not(CHILD_B)
tests whether the outer child node has no CHILD_B
child element on its own.
While node()[not(self::CHILD_B)]
checks whether any selected (outer) child node is not a CHILD_B
element.
Upvotes: 1