Project

Profile

Help

Support #4496

Unexpected order of data stored for a variable.

Added by Ken Holman 5 months ago. Updated 4 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
2020-03-23
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
9.8
Fix Committed on Branch:
Fixed in Maintenance Release:

Description

Below is the transcript of some unexpected results, boiled down to a simple example. I spent hours assuming that in the following declaration my copied variable content would be found in order in advance of the entity content:

<xsl:variable name="builtinPhrases" as="element(phrases)+"> <xsl:copy-of select="$additionalPhrases"/> &builtinPhrases; </xsl:variable>

Why would the variable content be stored in the variable after the entity content (as indicated by the output)? Is it related to how the stylesheet tree is constructed from the input source? Certainly it seems un-intuitive that the variable comes after the entity.

I've attached the sample file.

Thank you for your thoughts on this!

. . . . . . Ken

~/t $ cat unexpectedVariableResults.xsl

Hello world '> ]> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xsd" version="2.0">

<xsl:variable name="additionalPhrases" as="element(phrases)"> Don't worry, be happy </xsl:variable>

<xsl:variable name="builtinPhrases" as="element(phrases)+"> <xsl:copy-of select="$additionalPhrases"/> &builtinPhrases; </xsl:variable>

<xsl:output method="text"/>

<xsl:template match="/"> <xsl:value-of select="system-property('xsl:product-name'), system-property('xsl:product-version')"/> xsl:text </xsl:text> <xsl:value-of select="$builtinPhrases/@source"/> xsl:text </xsl:text> </xsl:template>

</xsl:stylesheet>~/t $ xslt2 unexpectedVariableResults.xsl unexpectedVariableResults.xsl SAXON HE 9.8.0.15 doctype variable ~/t $

unexpectedVariableResults.xsl (988 Bytes) unexpectedVariableResults.xsl Ken Holman, 2020-03-23 21:14

History

#1 Updated by Ken Holman 5 months ago

Retry with preformatted text:

~/t $ cat unexpectedVariableResults.xsl 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet
[
<!ENTITY builtinPhrases '
<phrases source="doctype">
  <phrase>Hello world</phrase>
</phrases>'>
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xsd"
  version="2.0">

<xsl:variable name="additionalPhrases" as="element(phrases)">
  <phrases source="variable">
    <phrase>Don't worry, be happy</phrase>
  </phrases>
</xsl:variable>
  
<xsl:variable name="builtinPhrases" as="element(phrases)+">
  <xsl:copy-of select="$additionalPhrases"/>
  &builtinPhrases;
</xsl:variable>

<xsl:output method="text"/>

<xsl:template match="/">
  <xsl:value-of select="system-property('xsl:product-name'),
                        system-property('xsl:product-version')"/>
  <xsl:text>&#xa;</xsl:text>
  <xsl:value-of select="$builtinPhrases/@source"/>
  <xsl:text>&#xa;</xsl:text>
</xsl:template>

</xsl:stylesheet>~/t $ xslt2 unexpectedVariableResults.xsl unexpectedVariableResults.xsl 
SAXON HE 9.8.0.15
doctype variable
~/t $ 

#2 Updated by Michael Kay 5 months ago

I think the essential issue here is that

$builtinPhrases/@source

sorts nodes into document order, and document order is unpredictable for nodes in different trees. Clearly the nodes constructed by xsl:copy-of and those constructed by expanding the entity are in different trees.

We've often tried to keep things intuitive by making document order across trees equate to the sequence of execution - if node A was created before node B, then node A is before node B in document order. That's been more an accident of the implementation than a deliberate design principle. One problem with it is that it can only be maintained in a multithreaded environment if threads communicate. So we've tended to move more towards distributed allocation of node identifiers rather than sequential allocation - which means in effect that it's truly random.

Try to get into the habit of using "!" rather than "/" if you don't actually want deduplication and sorting into document order. It means breaking the habits of a lifetime, but this expression should almost certainly be written as

$builtinPhrases!@source

#3 Updated by Ken Holman 4 months ago

Excellent observation and suggestion, Mike! Please forgive me for not having considered that. I figured it must have been something straightforward.

. . . . . . Ken

#4 Updated by Michael Kay 4 months ago

  • Tracker changed from Bug to Support
  • Status changed from New to Closed
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal

Please register to edit this issue

Also available in: Atom PDF