Java XPath歧义

Java XPath歧义,java,xml,oracle,xpath,Java,Xml,Oracle,Xpath,我正在处理XPath的以下片段 ancestor::contribution[1]/preceding-sibling::contribution[@speaker-reference][1] 我的Java应用程序(使用JDOM进行XPath查询)对此的解释与Oracle数据库(11g)不同。 我使用括号解决了这个问题,如下所示: (ancestor::contribution[1]/preceding-sibling::contribution[@speaker-reference])[1

我正在处理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
”的所有前
贡献中的第一个,而Oracle认为“具有属性
@speaker reference and position()=1的前
贡献中的第一个”

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

根据,方括号运算符
[…]
具有优先级19,而斜杠
/
具有优先级18。这意味着最后一个方括号
[1]
应应用于斜杠
/
后的表达式部分,而不是整个表达式。换句话说,甲骨文的解释是正确的

Java的实现*(在
/
表达式周围没有括号)提供正确的结果,它不符合标准。考虑用一个简短的例子提交一个bug并解释正在发生的事情。


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

根据您的描述,很难看出JDOM和Oracle在做什么。 但它们的不同行为显然是由反向轴的不同实现引起的

由于
祖先::贡献[1]
计算结果为空节点集或单个节点,因此我们可以将您的示例简化为以下情况,使用元素
x
作为上下文节点:

<doc>
   <contribution speaker-reference="a"/>
   <contribution speaker-reference="b"/>
   <contribution/>
   <x/>
</doc>  

选择
前面的同级::贡献[speaker reference]
将按文档顺序返回具有
speaker reference
属性的两个贡献节点

选择
(前面的同级::贡献[speaker reference])[1]
返回这两个节点中的第一个节点,即
speaker reference
=a的节点

选择前面的同级:贡献[speaker reference][1]
现在必须根据轴顺序解释位置谓词
[1]
。由于前面的同级
是反向轴,因此所选节点集必须按反向文档顺序处理。此节点集中的第一个位置是
扬声器参考
=b的节点


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

您不能添加一个简短的XML示例,并展示您希望选择的内容,以及JDOM和Oracle实际选择的内容吗。如果没有示例,很难理解您的分析。wero是对的:两种实现可能不同的潜在原因不止一个,例如轴的反向和绑定优先级。如果没有示例XML(包含几个
元素),就很难确保您对JDOM和Oracle DB工作方式的分析是正确和完整的,也很难验证哪个实现是错误的。我很确定这不是XPath歧义的问题。另请参阅我关于反转轴如何影响位置谓词含义的问题/答案:我同意。我很难从描述中找出哪个实现存在错误,但正确的解释是,
祖先::A[1]/前辈::x[1]
选择文档顺序中的最后一个匹配元素,而
(祖先::A[1]/前辈::x)[1]
选择文档顺序中的第一个匹配元素。