How to get real Node order from xpath expression (java)

If I have an XPath expression using preceding-sibling:: , I get the NodeList in the wrong 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 expression XPath: /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 Node :

  • book2

So how can I get the real order from such an expression:

/library/book[3]/preceding-sibling::book ?

+4
source share
3 answers

From http://www.w3.org/TR/xpath/#predicates

An axis is either the front axle or the reverse axis. An axis that only ever contains the node context or nodes that, after the node context in the order of the document, is the front axis. an axis that only ever contains the node context or nodes that were prior to the node context in the ordering document the inverse axis. Thus, the ancestor, ancestor, or oneself, the preceding and preceding axes of the brothers are inverse axes; all other axes are front axles. Since self-axis is always contained in most nodes, it does not matter whether it is a forward or reverse axis. the proximity position of a member of a node set with respect to an axis is defined as the position of a node in a node set ordered in the order of the document, if the axis is the front axis and reverse order of the document, if the axis is the reverse axis. The first position is 1.

About the order of the node result established after evaluating some XPath expression with a specific XPath engine, which is completely implementation dependent. In XSLT, it is explicitly defined when commands process a node, sorted in document order. In XPath, this is how node sets are defined in http://www.w3.org/TR/xpath/#section-Introduction :

node -set (unordered set of nodes without duplicates)

To do this, the standard DOM API has settings to get ordered and unordered results, as well as in XQuery

+5
source

A node -set has no order (the set is in order unordered). Most XPath APIs present the result of a node-set from evaluating an XPath expression in document order, which you observe and report in your question.

XPath is a read-only query language, and therefore it never changes the structure of the source XML document β€” the nodes in the node node of the selected nodes coincide with their structure in the original XML document. The structure, among other things, includes order.

If you need nodes returned in a different order than their original order in the XML document, this cannot be done only with XPath .

For this purpose, you can use XSLT:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="library"> <xsl:apply-templates select="*[not(position() >2)]"> <xsl:sort select="position()" data-type="number" order="descending"/> </xsl:apply-templates> </xsl:template> </xsl:stylesheet> 

when this conversion is applied to the provided XML document:

 <library> <book name="book1"> hello </book> <book name="book2"> world </book> <book name="book3"> !!! </book> </library> 

the desired, correct result is output:

 <book name="book2"> world </book> <book name="book1"> hello </book> 
+3
source

The preceding-sibling axis is indexed in reverse order. preceding-sibling::*[1] is the first previous sibling, i.e. one right in front of the node context.

Java seems to return a NodeList in document order. See @Alejandro's answer for more details on the order of node sets (and their presentation in the host language).

So an iteration of NodeList from the other end would be an option. Also try this XPath.

 /library/book[position() < 3] 

The result will be in document order again, but the expression is less complex than yours.

+2
source

Source: https://habr.com/ru/post/890440/


All Articles