【问题标题】:XPath ambiguityXPath 歧义
【发布时间】:2015-08-07 12:31:01
【问题描述】:

我正在使用 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 认为“具有@speaker-reference and position()=1 属性的前面contribution”。

我实际上打算进行第一种解释。我想知道根据 XPath 规范(找不到合适的位置),这两种解释中哪一种是正确的,或者规范是否允许表达式不明确。

【问题讨论】:

  • 您不能添加一个简短的 XML 示例并显示您期望选择的内容,以及 JDOM 和 Oracle 实际选择的内容。没有例子就很难理解你的分析。
  • wero 是对的:两种实现可能不同的潜在原因不止一个,例如轴的反向和绑定优先级。如果没有示例 XML(带有几个 <contribution> 元素),就很难确定您对 JDOM 和 Oracle DB 如何工作的分析是正确和完整的,或者很难验证哪个实现是错误的。我很确定这不是 XPath 歧义的问题。
  • 另请参阅我关于反向轴如何影响位置谓词含义的问题/答案:stackoverflow.com/a/18524097/423105

标签: java xml oracle xpath


【解决方案1】:

根据XML Path Language Specification,方括号运算符[..] 的优先级为19,而斜线/ 的优先级为18。这意味着最后一个方括号[1] 应该应用于表达式后面的部分斜线/,而不是整个表达式。也就是说,Oracle 的解释是对的。

Java 的实现* 不符合标准,它在/ 表达式周围不带括号为您提供正确的结果。考虑提交一个带有简短示例的错误并解释正在发生的事情。

* 讽刺的是,这也是 Oracle 的实现。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 我同意。我无法从描述中找出哪个实现存在错误,但正确的解释是 ancestor::A[1]/preceding-sibling::x[1] 选择文档顺序中的最后一个匹配元素,而 (ancestor::A[1]/preceding-sibling::x)[1] 选择文档顺序中的第一个匹配元素。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多