If I have an XPath expression that use preceding-sibling::
, I get the NodeList
not in the right order. How can I get the right order? Example:
<library>
<book name="book1">
hello
</book>
<book name="book2">
world
</book>
<book name="book3">
!!!
</book>
</library>
If I try to evaluate the XPath expression: /library/book[3]/preceding-sibling::book
, I get this order:
- book1
- book2
But if I try to evaluate : /library/book[3]/preceding-sibling::book[1]
, I get the Node
:
- book2
So, how can I get the real order from this kind of expression:
/library/book[3]/preceding-sibling::book
?
The
preceding-sibling
axis is indexed in reversed order.preceding-sibling::*[1]
is the first preceding sibling, i.e. the one right before the context node.Apparently, Java returns the
NodeList
in document order. See @Alejandro's answer for more details about the order of node sets (and their representation in the host language).So iterating the
NodeList
from the other end would be an option. Also try this XPath.The result will be in document order again, but the expression is less complex than your's.
From http://www.w3.org/TR/xpath/#predicates
About the order of the result node set after evaluation of some XPath expression with an specific XPath engine, that's completely implementation dependant. In XSLT, it's explicitly defined when instructions treats node set sorted in document order. In XPath this is how node sets are defined in http://www.w3.org/TR/xpath/#section-Introduction :
That's why in the standard DOM API there are settings to get ordered and unordered results as well as in XQuery
A node-set doesn't have order (sets are unordered by definition). Most XPath APIs present the node-set result from evaluating an XPath expression in document order, which is what you observe and report in your question.
XPath is a query (read-only) language and as such it never modifies the structure of the source XML document -- the nodes in the nodeset of selected nodes is the same as their structure in the source XML document. Structure, among other things, includes order.
In case you need the nodes returned in another order than their original order in the XML document, this cannot be done with XPath alone.
One can use XSLT for this purpose:
when this transformation is applied on the provided XML document:
the wanted, correct result is produced: