问题描述
我正在使用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读作“带有@speaker-reference
属性的所有前面contributions
的第一个”,而Oracle认为“前面的contribution
是@speaker-reference and position()=1
”。
我实际上打算进行第一次解释。 我想知道根据XPath规范(无法找到合适的位置)或者规范是否允许表达式不明确,这两种解释中的哪一种是正确的。
1楼
根据 ,方括号操作者[..]
的优先级19,而斜线/
具有优先权18。这意味着最后方括号[1]
应该斜线后施加到表达的所述部分/
,不是整个表达。
换句话说,Oracle的解释是正确的。
Java的实现* ,它在/
expression周围没有括号的情况下为您提供正确的结果,不符合标准。
考虑使用简短示例提交错误并解释正在发生的事情。
*具有讽刺意味的是,这也是Oracle的实施。
2楼
鉴于您的描述,很难看出JDOM和Oracle正在做什么。 但是它们的不同行为显然是由反向轴的的不同实现引起的。
由于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的节点。
希望这可以让您澄清哪些实现是正确的。