3

I have an xpath-expression like this:

element[@attr="a"] | element[@attr="b"] | element[@attr="c"] | … which is an »or« statement. So can I create an expression that guarantees the result to appear in the order as in the query, even if the elements appear in a different order in the document?

f.e. an document fragment in this order:

<doc>
    <element attr="c" />
    <element attr="b" />
    <element attr="a" />
    .
    .
    .
</doc>

and a result list ordered like this:

[0] <element attr="a" />
[1] <element attr="b" />
[2] <element attr="c" />
.
.
.
philipp
  • 15,947
  • 15
  • 61
  • 106

2 Answers2

5

The | operator computes the union of its operands and with XPath 1.0 you simply get a set of nodes, the order is undefined, though most XPath APIs then return the result in document order or allow you to say which order you want or whether order matters (see for instance http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathResult).

With XPath 2.0 you get a sequence of nodes ordered in document order, with XPath 2.0 if you want the order of your subexpressions you would need to use the comma operator, not the union operator i.e. element[@attr="a"] , element[@attr="b"] , element[@attr="c"].

So for e.g. /doc!(element[@attr="a"] , element[@attr="b"] , element[@attr="c"]) you get the element nodes in the wanted order.

XPath 3.1 online fiddle.

Of course you can also sort the elements in XPath 3.1 e.g.

sort(/doc/element, (), function($el) { $el/@attr })
Martin Honnen
  • 160,499
  • 6
  • 90
  • 110
  • thank you! Unfortunately gives it an empty result in chromium – philipp Oct 06 '12 at 12:38
  • Please be more specific, what exactly gives an empty result? – Martin Honnen Oct 06 '12 at 13:09
  • I have tried using the `,` as separator in the query, but it did not work in chromium, an empty result came back.. – philipp Oct 06 '12 at 13:16
  • Well the comma operator is new in XPath 2.0, it does not exist in XPath 1.0, and as far as I know the XPath implementations in current browsers are XPath 1.0 implementations so I suspect Chromium gives you an error when trying such an expression, check its error console. With XPath 1.0 all you can use is the union operator but that does not help for your purpose of getting a certain order of nodes. – Martin Honnen Oct 06 '12 at 13:32
4

can I create an expression that guarantees the result to appear in the order as in the query, even if the elements appear in a different order in the document?

  1. Not with any XPath 1.0 engine -- they return the resulting XmlNodeList in document order.

  2. With XPath 2.0 one can specify that a sequence is to be returned, using the comma , operator, like this:

    element[@attr="a"] , element[@attr="b"] , element[@attr="c"]

  3. Finally, If you are limited with an XPath 1.0 implementation, one way of getting the results in the desired order is to evaluate these three XPath expressions:

    element[@attr="a"]

    element[@attr="b"]

    element[@attr="c"]

Then you can access the first result first, the second result -- second and the third result -- third.

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431