XPath uncertainty
I am working with the following XPath snippet
ancestor::contribution[1]/preceding-sibling::contribution[@speaker-reference][1]
My Java application (using JDOM for XPath queries) interprets this differently than our Oracle database (11g). I was able to solve the problem using brackets like this:
(ancestor::contribution[1]/preceding-sibling::contribution[@speaker-reference])[1]
So it seems that JDOM reads the xpath as "first and foremost contributions
with an attribute @speaker-reference
", whereas Oracle thinks "previous contribution
with an attribute @speaker-reference and position()=1
".
I really set out to make the first interpretation. I'm wondering which of the two interpretations is correct according to the XPath spec (can't find a suitable place to look) or the spec allows expressions to be ambiguous.
source to share
According to the XML Language Specification , the square brackets operator [..]
has priority 19, and the slash /
has priority 18. This means that the last square brackets [1]
must be applied to the part of the expression after the slash /
, and not to the entire expression. In other words, Oracle's interpretation is correct.
A Java implementation * that gives the correct result without parentheses around the expression /
is not standard compliant. Consider filing an error with a short example and an explanation of what is happening.
* Ironically, this is an Oracle implementation.
source to share
Given your description, it is not easy to understand what JDOM and Oracle are doing. But their different behavior seems to be due to a different implementation of the proximity of the location on the reverse axis.
Since it ancestor::contribution[1]
computes an empty set of node or one node, we can simplify your example in the following situation by using an element x
as the context of a node:
<doc>
<contribution speaker-reference="a"/>
<contribution speaker-reference="b"/>
<contribution/>
<x/>
</doc>
The selection preceding-sibling::contribution[speaker-reference]
returns two input nodes with the attribute speaker-reference
in document order.
The selection (preceding-sibling::contribution[speaker-reference])[1]
returns the first of the two nodes, which is speaker-reference
= a.
When selected preceding-sibling::contribution[speaker-reference][1]
, the position predicate [1]
should now be interpreted according to the axis order. Since preceding-sibling
is a reverse axis, the selected node-set must be processed in reverse document order. The first position in this node-set is node c speaker-reference
= b.
Hopefully this will allow you to clarify which implementation got right.
source to share