用于选择具有公共属性的所有节点的XPath表达式

Jac*_*ack 11 xml xpath

我正在阅读XML的一本书说,要选择XML文件中具有特定属性的所有节点,请使用以下语法:

//*/@_attribute_
Run Code Online (Sandbox Code Playgroud)

我不明白的是为什么需要星号.据我了解,表达式//选择根节点的所有后代.那么,不会// @ lang,例如,选择具有名为"lang"属性的根节点的所有后代?我甚至无法解释星号在上面的表达式中的含义(我知道星号通常意味着"全部").如果有人可以为我分解,我真的很感激.

谢谢

小智 15

嗨,我正在读XML的书说要选择XML文件中具有特定属性的所有节点,请使用以下语法:

//*/@attribute

那是错的.它将扩展到:

/descendant-or-self::node()/child::*/attribute::attribute
Run Code Online (Sandbox Code Playgroud)

含义:节点的任何元素子节点的所有attribute属性都是根文档本身或其后代之一

你需要:

/descendant::*[attribute::attribute]
Run Code Online (Sandbox Code Playgroud)

或缩写形式

//*[@attribute]
Run Code Online (Sandbox Code Playgroud)

关于*:formaly是名称测试而不是节点类型测试.在XPath 1.0中,没有元素类型测试.在XPath 2.0中你有element().那么,为什么只选择元素呢?嗯,事实并非如此.轴具有主节点类型,来自http://www.w3.org/TR/xpath/#node-tests:

每个轴都有一个主节点类型.如果一个轴可以包含元素,那么主节点类型就是元素; 否则,它是轴可以包含的节点类型.从而,

  • 对于属性轴,主节点类型是属性.
  • 对于名称空间轴,主节点类型是名称空间.
  • 对于其他轴,主节点类型是元素.

这就是为什么*,child::*,self::*,descendant::*,等选择的元素,但@*还是attribute::*namespace::*选择的属性或范围的命名空间.

关于谓词([@attribute]部分):评估此表达式,每个节点按最后一步选择.它需要一个用于过滤的布尔值.attribute::attribute对于空节点集,节点集的布尔值(这是结果)为false,否则为true.


Dim*_*hev 13

这个问题的标题是:

用于选择具有公共属性的所有节点的XPath表达式

然而,问题的文本没有讨论如何找到具有共同属性的所有节点 - 因此标题可能不正确.

要查找具有公共属性命名的所有节点x(BTW,只有元素节点可以具有属性),请使用:

//*[@x]
Run Code Online (Sandbox Code Playgroud)

用途:

//@x
Run Code Online (Sandbox Code Playgroud)

选择xXML文档中指定的所有属性.这可能是最短的表达方式.

没有错:

//*/@x
Run Code Online (Sandbox Code Playgroud)

除了它稍长.

这是一个简写:

/descendant-or-self::node()/child::*/attribute::x
Run Code Online (Sandbox Code Playgroud)

并选择xXML文档中的所有属性.

有人可能会认为这个表达式没有选择x文档中top元素的属性.这是一个错误的结论,因为第一个位置步骤:

/descendant-or-self::node()
Run Code Online (Sandbox Code Playgroud)

选择文档中的每个节点,包括root(/)本身.

这意味着:

/descendant-or-self::node()/child::*
Run Code Online (Sandbox Code Playgroud)

选择每个元素,包括top元素(在格式良好的XML文档中是根节点的唯一子元素).

因此,当/@x最后添加最后一个位置步骤时,这将选择x前两个位置步骤所选择的所有节点的所有x属性- 即XML文档中所有元素节点的所有属性.

  • +1感谢您的澄清.我总是喜欢阅读你的答案. (2认同)