[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

Re: [xsl] Can I predict the build order of nodes?


Subject: Re: [xsl] Can I predict the build order of nodes?
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Sun, 14 Feb 2010 14:09:55 -0500

At 2010-02-14 10:50 -0800, Kevin Brown wrote:
I noticed an interesting build order/selection issue between Saxon and
Microsoft XSL transforms ... in my style sheet I have:

<xsl:param name="stylemasterfile">
     <xsl:value-of select="/winelist/stylemasterfile"/>
</xsl:param>

The above assigns the text value of the first stylemasterfile element child of winelist in document order to the variable $stylemasterfile. It is a bit wasteful to build a result tree fragment for this ... you could have:


<xsl:param name="stylemasterfile" select="/winelist/stylemasterfile"/>

<xsl:param name="stylemasterset" select="document($stylemasterfile)/styles |
/winelist/styles"/>

<xsl:variable name="stylemaster" select="$stylemasterset[last()]"/>

There is no prescribed document order between two different trees. For any given processor the nodes of one tree are persistently in the same document order before the nodes of another tree, but another processor can just as well have a different persistent order between two trees.


The XML may have:

1) a file pointer (in /winelist/stylemasterfile) which contains <styles>
2) an embedded <styles> (at /winelist/styles)
3) both

If it contains both, the rule should be to select the embedded one.

But selecting $stylemasterset[last()] and testing I noted that they are in
opposite order on the two XSLT transformers when both exist.

Without saying which is which ... what is the right answer?

Both!


What do you think is the proper result of this:

document($stylemasterfile)/styles | /winelist/styles

Internal styles from /winelist/styles
External styles from document($stylemaster)/styles

or

External styles from document($stylemaster)/styles
Internal styles from /winelist/styles

Or does the spec make no determination of order?

Precisely.


Would something like this help?

<xsl:variable name="in" select="/"/>

<xsl:param name="stylemasterfile" select="/winelist/stylemasterfile"/>

  <xsl:variable select="document($stylemasterfile)/
                        styles[not($in/winelist/styles)][last()] |
                        $in/winelist/styles[last()]"
                name="stylemaster"/>

  ... which is to say "use the last of the external document only if
      there are no internal styles, in union with the last of the
      internal styles

If the styles element isn't repeating and you are only using last to distinguish between the two, then it is simply:

  <xsl:variable select="document($stylemasterfile)/
                        styles[not($in/winelist/styles)] |
                        $in/winelist/styles"
                name="stylemaster"/>

In XSLT 2 (which I'm guessing is out of bounds for you because you cite Microsoft) it would be accomplished with a sequence:

( /winelist/styles , document($stylemasterfile)/styles ) [1]

I hope this helps.

. . . . . . . . . . . . . Ken

--
XSLT/XQuery/XPath training after http://XMLPrague.cz 2010-03-15/19
XSLT/XQuery/XPath training:   San Carlos, California 2010-04-26/30
Vote for your XML training:   http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman@xxxxxxxxxxxxxxxxxxxx
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal


Current Thread
Keywords