Project

Profile

Help

Mixed up order in temporary node sequences as function result [Saxon 9.7.0.15J / Saxon-PE 9.8.0.3J]

Added by Nico Kutscherauer over 6 years ago

Dear Saxonica team,

I think I found a bug in 9.7.015+ (in Oxygen XML Developer 19). Please have a look at my XSLT stylesheet:

(I made it as short as possible, to reproduce the bug)





	


	

		
		
			

				
			
			

				
			
		
	

	

		
		
			
				###
			
			
				text
			
			
				###
			
		
		

		

			
				
					
						
							
						
					
				
				
					
				
			
		

	


My result is:



   
      
         ###
      
      
         text
      
      
         ###
      
   
   
      ###
      ###
      text
   

The is OK, but for the copy-wt I would expect


...
   
      ###
      text
      ###
   
...

For some reasons the condition breaks the order, but only if I ask for the w:t's. If I make a reverse condition (just using not()), I get the "text" as first, then the hashes.

The issue does not happen, if I do one of the following:

  • Use in xsl:when and xsl:otherwise both the xsl:copy instruction or both the xsl:copy-of instruction
  • Do not wrap the main code in a function, just do it in the main template
  • Remove the condition

I tried it also with:

  • Saxon-PE 9.8.0.3J in command line. There I had the same issue
  • Oxygen 18.1 with Saxon 9.6.0.7. There I get the expected result.

Hope this helps.

Best Regards, Nico

Saxon_issue_order_of_temp_tree.xslt (1.74 KB) Saxon_issue_order_of_temp_tree.xslt Complete stylesheet to reproduce it

Replies (2)

RE: Mixed up order in temporary node sequences as function result [Saxon 9.7.0.15J / Saxon-PE 9.8.0.3J] - Added by Michael Kay over 6 years ago

Saxon's behaviour here might be surprising, but I don't think it is non-conformant.

Your function is copying three elements to create a sequence of three newly created parentless elements in variable $wrs,

When you do

            
                
            

The children of the copy-wr element will reflect the order of the sequence in $wrs.

When you do

            
                
            

the "/" operator causes the nodes in $wrs to be sorted into document order. But the relative order of three parentless elements, when sorted into document order, is undefined, so Saxon can choose any order it likes. If you want to retain the order of the sequence in $wrs you should use the "!" operator rather than "/". (I would actually recommend replacing very many uses of "/" by "!", because the sorting into document order often imposes a quite unnecessary cost, quite apart from making the results implementation-dependent.)

Although the document-order of parentless nodes is undefined, Saxon generally tries to avoid creating this kind of surprise, (a) because we don't like this kind of bug report, and (b) because the fastest way of sorting things into an undefined order is to avoid sorting them at all. But there's a particular combination of circumstances here that means this approach isn't working in this case.

The three nodes in $wrs are represented internally by instances of TinyElementImpl, VirtualUntypedCopy, and TinyElementImpl respectively. TinyElementImpl means we have a materialized in-memory tinytree rooted at an element node; VirtualUntypedCopy means we represent the node as a pointer to the original node that was "copied", but with new document identity. When we compare two parentless nodes to establish their relative position in document order, we look at the document number held in the TreeInfo for the tree. For a TinyTree we are generating document numbers eagerly (at the time the tree is created), while for a VirtualUntypedCopy we are generating the document number lazily, on first use. So the VirtualCopy gets a higher document number than the two TinyTrees, and therefore appears later in document order.

We could change this, but it might have performance implications, and I'm reluctant to do that purely to avoid surprises for a stylesheet that is actually making unwarranted assumptions about the spec.

RE: Mixed up order in temporary node sequences as function result [Saxon 9.7.0.15J / Saxon-PE 9.8.0.3J] - Added by Nico Kutscherauer over 6 years ago

Hi Michael,

thank you for the explanation! I see now, I still didn't understood the sequence / tree model of XSLT 2 completely.

For me it was surprising, that

with Saxon 9.6 I got my expected results. So you may have changed something, which improves the performance? But this means, that some stylesheets will not work with the newer Saxon version correctly. I don't think, that I'm the only one who uses the "/" without respecting the differences between the sequence and the document order.

it depends on the choose-when condition whether VirtualUntypedCopy comes first or the TinyElementImpl's. So the order of the when/otherwise statements have influence of the result.

But of course this is a very special case and you can keep it, as it is. I know in future, that I have to respect more the document association of the nodes, when I'm using the "/".

Best Regards, Nico

    (1-2/2)

    Please register to reply