为什么 <xsl:apply-templates select="node()[not(self::CHILD_B)]" /> 和 <xsl:apply-templates select="node()[not(CHILD_B)]" /> 不一样?

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

我目前正在学习 XSLT,对我在书中找到的一个示例有点困惑。对select所有节点,除了某个节点,它说使用:

<xsl:apply-templates select="node()[not(self::CHILD_B)]" />

这行得通,但我想知道为什么 self:: 部分是必需的?为什么 <xsl:apply-templates select="node()[not(CHILD_B)]" /> 不起作用?毕竟 <xsl:apply-templates select="CHILD_B" /> 会对 select 元素起作用(没有 self:: 部分),那么为什么我们在排除它时需要 self:: 部分?

示例:

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>

在谓词内部,上下文节点更改为在谓词左侧的表达式中选择的任何节点,因此 node()[not(CHILD_B)] 查找上下文节点的任何子节点,但随后在谓词内部要评估,此子节点是上下文节点,因此 not(CHILD_B) 测试外部子节点是否没有自己的 CHILD_B 子元素。

虽然 node()[not(self::CHILD_B)] 检查任何选定的(外部)子节点是否不是 CHILD_B 元素。