The string-join function does not honour the order of the nodes passed to it. It always returns the nodes in the order they appear in the document.
This code in eXide:
let $index :=
<root>
<forename>Thomas</forename>
<surname>Pennant</surname>
</root>
let $person := string-join($index/(surname | forename), ' ')
return $person
Will always return 'Thomas Pennant', even though (surname | forename) above might make one think that it should return Pennant Thomas.
eXist-db 5.2
openjdk 13.0.2 2020-01-14
centOS 7
please could you (try to) strip down the query a bit? e.g. is the predicate [@xml:id eq '1'] important or not? Is there a difference with a dynamically generated document and a in-database stored document?
I've updated my post. I wouldn't know how to strip it down further!
There's no difference between dynamically generated documents and in-database stored document.
For xquery related questions I'd recommend to check with Saxon first; here also Thomas Pennan is returned, so we need to study the meaning of | first; it is the union set operator (see https://www.w3schools.com/xml/xpath_operators.asp) so whatever comes first is matched. That is what you see....
In (surname | forename), the | is an OR operator. Thus, the expression will always return matching results鈥攁ll surname OR forename elements鈥攊n document order. If you want to select nodes in a particular order, use , instead鈥攃onstructing a new sequence of all surname elements, then all forename elements:
xquery version "3.1";
let $index :=
<root>
<forename>Thomas</forename>
<surname>Pennant</surname>
</root>
let $person := string-join($index/(surname, forename), ' ')
return $person
This is not a bug then, closing.