XPath child::* 与 child::node()

XPath child::* vs child::node()

我正在处理 XSLT 转换,我发现了一个我无法回答的有趣问题:

child::*child::node()有什么区别 ?

我想创建一个条件,将子元素的数量定为 1,在本例中:

<xsl:if test="parent[count(child::*) eq 1])"> 

对比

<xsl:if test="parent[count(child::node()) eq 1])"> 

会有什么区别?

What's the difference between child::* and child::node().

引用自here

  • * 匹配任何元素
  • node() 匹配属性节点和根节点以外的任何节点

所以child::*只匹配子元素和 child::node() 匹配除属性和根节点之外的任何子节点。这些可以是七种节点类型中的五种:元素、注释、文本和命名空间节点以及处理指令 (see here)。

要理解XPath中child::*child::node()的区别,不仅要理解*node()节点测试的区别,还要理解*node()节点测试的概念轴的 principal node type...

主节点类型

规则:如果一个轴可以包含元素,那么它的主节点类型element;否则,它是轴可以包含的节点类型。 (比如attribute轴的主节点类型attribute,因为它只能包含属性。)

child轴可以包含元素,所以子轴的主节点类型element.

每个轴的节点测试

因此,child::*child::node()的区别在于

  • child 轴上的 * 节点测试对所有 child 元素成功 上下文节点,因为 * 节点测试成功 所有主要节点类型 的节点(此处为 element,而
  • node() 节点的所有 子节点 节点测试成功 上下文节点,因为 node() 节点测试成功 所有节点类型 。但是,请注意并非所有节点类型都可以位于 child 轴上。下面是七种类型的节点以及它们是否可以出现在子轴上:
    • root:不,根据定义,根节点不是其他节点的子节点。
    • 元素:是
    • 文本:是
    • 属性:不,属性有自己的轴。
    • namespace: 不,命名空间有自己的轴。
    • 处理指令:是
    • 评论:是

因此,child::* 匹配上下文节点的所有 元素 子元素,child::node() 匹配所有 元素、文本和上下文节点的处理指令 个子节点。