最近我需要评估 HTML 文档节点上的 XQuery。基本上,我需要从 body 元素的第一个子元素中选择所有具有 href 属性的元素。我添加了一个小例子来解释:
<html>
<body>
<a href="http://www.google.be"/>
</body>
</html>
在这种情况下,期望的提取结果显然是:
<a href="http://www.google.be"/>
我的第一个想法是使用 //body/*[1]//*[@href]
因为:
//body
匹配 body 元素,无论它在哪里/*[1]
匹配 body 元素的第一个子元素//*[@href]
匹配当前元素的所有后代或自身
我认为这可行,但在提供的示例中,XQuery 没有给出任何结果。
但是,我仔细阅读并发现了以下内容(来源:http://www.keller.com/xslt/8/):
Alternate notation for "//": descendant-or-self::node()
所以我将我的 XQuery 更改为 //body/*[1]/descendant-or-self::node()[@href]
,这一次,结果是正确的。
我的问题://和 descendant-or-self::node() 有什么区别?我在这里 ( What's the difference between //node and /descendant::node in xpath? ) 和这里 ( http://www.w3.org/TR/xpath/#axes ) 发现的内容是:
//
is short for/descendant-or-self::node()/
. For example,//para
is short for/descendant-or-self::node()/child::para
.
这让我得出结论,//
和 /descendant-or-self::node()
不可互换(可能是因为终止 /
最后?),但是有人可以告诉我是否有 /descendant-or-self::node()
的简写吗?
最佳答案
您的第一个 XPath 表达式 (//body/*[1]//*[@href]
) 实际上表示您用自然语言描述的内容://body/*[1 ]
是 body 元素的第一个子元素,//*[@href]
选择具有 @href
属性的第一个元素(下方)。
在您的示例中, anchor 标记下方没有元素具有此类属性。例如,此查询将匹配
<html>
<body>
<p>
<a href="http://www.google.be"/>
</p>
</body>
</html>
此查询的非缩写版本是:
//body/*[1]/descendant-or-self::node()/*[@href]
对比一下你的第二个查询,问题应该很容易看出:
//body/*[1]/descendant-or-self::node()[@href]
关于html - XQuery://vs descendant-or-self::node(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21240221/