Q:

How to select elements in a specific order with XPath

I have a XML file with nodes (Z) containing child nodes (H, W, P) in a random order:
<X>
  <Y>
    <Z>
      <H>Hello</H>
      <W>World</W>
      <P>!</P>
    </Z>
    <Z>
      <P>!</P>
      <W>World</W>
      <H>Hello</H>
    </Z>
  </Y>
</X>

And I would like to select the content of the child nodes in a given order.
I tied this:
/X/Y/Z/*[self::H or self::W or self::P]/text()

But this will keep the wrong order:
Hello World !
! World Hello

I need some way to select the W and P relative to H in a sequence. How can I do that?
I tried this:
/X/Y/Z/(H,W,P)/text()

But the order is still wrong.
Edit: The questions suggests that I need only the text portion, but I need the node and not only the text. The reason is, that the XPath text() function seems to have a problem with CDATA sections.

A:

For XPath 2:
Using the / to select nodes will always return the nodes in document order, no matter how you write it.
If you, however, select atomic values instead of nodes it will keep the order:
/X/Y/Z/concat(H,W,P)

You can also use for-in-return which will never change the order: 
for $z in /X/Y/Z return ($z/H,$z/W,$z/P)

For XPath 3: 
In a real modern implementation you can also use ! instead of / which will also always keep the order, and is otherwise  the same as /   (and it will also keep duplicates): 
 /X/Y/Z ! (H,W,P) ! text()

