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.

+3


source to share


2 answers


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.

+3


source


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.

+3


source







All Articles