T-Dawg
T-Dawg

Reputation: 83

Why are <xsl:apply-templates select="node()[not(self::CHILD_B)]" /> and <xsl:apply-templates select="node()[not(CHILD_B)]" /> not the same?

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

Answers (1)

Martin Honnen
Martin Honnen

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

Related Questions