The XPath if
is returning the original nodes from the input, still attached to their original contexts in the input tree. The choose
version is returning new nodes that are copies of the input nodes, and when you navigate the preceding-sibling::
axis from these nodes you're only looking at the temporary tree in the variable, not the nodes' original context in the source XML.
If you want to capture the original nodes rather than copies in the xsl:choose
variant then use xsl:sequence
instead of xsl:copy-of
. You will also need to make the variable typed by adding something like as="node()*"
. Section 9.4 of the XSLT 2.0 spec explains why (my bold):
A document node is created implicitly when evaluating an
xsl:variable
,xsl:param
, orxsl:with-param
element that has non-empty content and that has noas
attribute. [...] The value of the variable is a single node, the document node of the temporary tree. The content of the document node is formed from the result of evaluating the sequence constructor
If you do provide as="node()*"
then the nodes produced by the sequence constructor (i.e. the content of the xsl:variable
element) are used as-is rather than forming the content of a new implicit document node.