为什么 XPath 的节点测试 node() 不返回属性 Nodes?



我一直在研究XPath的节点测试(此处为文档(,并在一些示例xml上进行了测试。

<apartment residents="4" shared="true"> 
fries
<!-- potatosalad -->
</apartment>

虽然属性//apartment/@*的Kindtest将返回居民共享,这意味着它们都是公寓节点的子级,但任何类型的//公寓/节点((都将返回文本节点炸薯条以及注释节点potatosalad,但不返回属性节点1uridentshared

这似乎违背了我的直觉,我想知道:这有充分的理由吗?

XPath//apartment/node()将选择apartment元素的所有子节点,即*processing-instruction()comment()text()

属性和名称空间的特殊之处在于,它们的父元素是它们"是"的元素;附于";,但它们不被视为child节点,并且不会从child轴中选择。

关于规格中的子轴的信息(我添加了粗体以示强调(:

https://www.w3.org/TR/2017/REC-xpath-31-20170321/#axes

子轴包含上下文节点的子节点,这些子节点是第5.3节子访问器返回的节点。

注意:只有文档节点和元素节点具有子节点。如果上下文节点是任何其他类型的节点,或者上下文节点是空文档或元素节点,则子轴是空序列文档节点或元素节点的子节点可以是元素、处理指令、注释或文本节点。属性、命名空间和文档节点永远不能显示为子节点

https://www.w3.org/TR/xpath-datamodel-31/#ElementNodeOverview

  1. 不包括属性和命名空间节点,如果节点N具有父元素E,则N必须在E的子元素中

"为什么?"问题总是很难回答。我们可以指出规范中的规则,即它就是这样做的,但我们很少能发现委员会在做出决定时的想法,如果真的有意识的话。我们真正能做的就是推测为什么有人会认为这是一个好的设计。

当您意识到node()NodeTest,在这里用作AxisStep时,这个决定是有意义的。AxisStep的形式为[Axis::]NodeTestAxis部分默认为"child::"。有一个"子或属性"轴并不是很有用,因为child-or-attribute::XYZ是不明确的。所以没有,这意味着当NodeTest恰好是node()时,将其用作默认轴是没有意义的。

基本上,axis步骤有一个完整的语法,它是高度正交的(你可以将任何axis与任何NodeTest一起使用(,正交性受到语言设计者的高度重视。然后是一个缩写语法,使常见情况不那么冗长;缩写不那么正交,但有一些一致性,其中一个一致性规则是默认轴是子轴,除非(在2.0中(NodeTest只选择属性或名称空间节点。

最新更新