XPath child::*与child::node()的区别

7
我正在处理一个XSLT转换的工作,发现了一个有趣的问题,但我无法回答:
child::*child::node()之间有什么区别?
我想创建一个条件,在这种情况下将子元素的数量限制为1:
<xsl:if test="parent[count(child::*) eq 1])"> 

vs

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

有什么不同之处吗?


1
规范已经在线了,尝试阅读https://www.w3.org/TR/xpath20/#node-tests并告诉我们您不理解的部分。 - Martin Honnen
2
很好的问题!XPath存在一些微妙的差异,这些差异常常被许多非专业用户所忽略。有关详细信息,请参见我下面的回答 - kjhughes
在你在这里提问之前,你在哪里寻找过这个问题的答案? - Michael Kay
2个回答

8
为了理解XPath中child::*child::node()之间的区别,需要理解*node()节点测试之间的区别以及主要节点类型的概念。

主要节点类型

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

每个轴的节点测试

因此,child::*child::node()之间的区别在于:
  • 对于上下文节点的所有子元素*节点测试都成功了,因为*节点测试对于主节点类型(此处为element)的所有节点都成功,而子节点node()节点测试对所有节点类型都成功。但是请注意,不是所有节点类型都可以在child轴上出现。以下是七种节点类型及其是否可以出现在子级轴上:
    • 根节点:否,根据定义,根节点不是任何其他节点的子节点。
    • 元素:是
    • 文本:是
    • 属性:否,属性有它们自己的轴。
    • 命名空间:否,命名空间有它们自己的轴。
    • 处理指令:是
    • 注释:是
因此,child::*匹配上下文节点的所有元素子节点,child::node()匹配上下文节点的所有元素、文本和处理指令子节点。

好的答案。这个差异也被W3 Schools记录下来了。 - Ed Graham

3
“child::*”和“child::node()”有什么区别?
引用自这里的话:
- “*”匹配任何元素 - “node()”匹配除属性节点和根节点以外的任何节点
因此,“child::*”只匹配子元素,“child::node()”匹配除属性节点和根节点以外的任何子节点。这些可以是七个节点类型中的五个:元素、注释、文本和命名空间节点和处理指令(请参阅此处)。

CDATA 什么时候成为节点类型了?!w3schools 什么时候成为参考资料了?!在 XPath 规范 中,列出了七种节点类型:根、元素、文本、属性、命名空间、处理指令和注释。 - michael.hor257k
@michael.hor257k:感谢您纠正我。由于过去的编码经验,我对CDATA有些误解,并没有正确地记在脑海中。 - zx485
这基本上是正确的(+1),但完整的答案比评论中能容纳的更微妙,因此我添加了一个新答案来解释。(*作为节点测试不仅可以匹配元素,而且node()作为节点测试也可以匹配属性;它们在child轴上的位置隐含地添加了这些限制。有关详细信息,请参见我的答案。) - kjhughes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接