当前位置: 代码迷 >> java >> XPath模棱两可
  详细解决方案

XPath模棱两可

热度:75   发布时间:2023-07-25 19:29:29.0

我正在使用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规范(无法找到合适的位置)或者规范是否允许表达式不明确,这两种解释中的哪一种是正确的。

根据 ,方括号操作者[..]的优先级19,而斜线/具有优先权18。这意味着最后方括号[1]应该斜线后施加到表达的所述部分/ ,不是整个表达。 换句话说,Oracle的解释是正确的。

Java的实现* ,它在/ expression周围没有括号的情况下为您提供正确的结果,不符合标准。 考虑使用简短示例提交错误并解释正在发生的事情。

*具有讽刺意味的是,这也是Oracle的实施。

鉴于您的描述,很难看出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的节点。

希望这可以让您澄清哪些实现是正确的。