我正在使用XPath的以下片段
ancestor::contribution[1]/preceding-sibling::contribution[@speaker-reference][1]
我的Java应用程序(使用JDOM进行XPath查询)与Oracle数据库(11g)的解释不同。 我能够通过使用括号解决问题,如下所示:
(ancestor::contribution[1]/preceding-sibling::contribution[@speaker-reference])[1]
所以似乎JDOM正在读取xpath作为"前面的contributions
中的第一个具有属性@speaker-reference
"而Oracle认为"前面的contribution
带有属性@speaker-reference and position()=1
"。
我实际上打算第一次解释。我想知道根据XPath规范(无法找到正确的位置)或者规范是否允许表达式含糊不清,这两种解释中的哪一种是正确的。
答案 0 :(得分:3)
根据XML Path Language Specification,方括号运算符[..]
的优先级为19,而斜杠/
的优先级为18.这意味着应该应用最后的方括号[1]
斜杠/
之后的表达式部分,而不是整个表达式。换句话说,甲骨文的解释是正确的。
Java的实现 * ,它为您提供了在/
表达式周围没有括号的正确结果,不符合标准。考虑使用简短示例提交错误并解释正在发生的事情。
* 具有讽刺意味的是,这也是Oracle的实施。
答案 1 :(得分:3)
鉴于您的描述,很难看出JDOM和Oracle正在做什么。 但是他们的不同行为显然是由反轴的proximity position的不同实现引起的。
由于ancestor::contribution[1]
求值为空节点集或单个节点,我们可以将示例简化为以下情况,使用元素x
作为上下文节点:
<doc>
<contribution speaker-reference="a"/>
<contribution speaker-reference="b"/>
<contribution/>
<x/>
</doc>
选择preceding-sibling::contribution[speaker-reference]
会按文档顺序返回带有speaker-reference
属性的两个贡献节点。
选择(preceding-sibling::contribution[speaker-reference])[1]
会返回这两个节点中的第一个节点,即speaker-reference
= a。
现在必须根据轴顺序解释选择preceding-sibling::contribution[speaker-reference][1]
位置谓词[1]
。由于preceding-sibling
是反向轴,因此必须以反向文档顺序处理所选节点集。此节点集中的第一个位置是speaker-reference
= b。
希望这可以让你澄清哪些实现是正确的。