Re: [xsl] learned a lesson about XPath variable evaluations sorting in document order

Subject: Re: [xsl] learned a lesson about XPath variable evaluations sorting in document order
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 17 Feb 2023 00:21:28 -0000
We really should be encouraging everyone to use "!" instead of "/" far more
often. It's simpler and usually better.

Michael Kay
Saxonica

> On 16 Feb 2023, at 23:34, Chris Papademetrious
christopher.papademetrious@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
> Hi everyone,
>
> Given the following input:
>
> <?xml version="1.0" encoding="utf-8" ?>
> <root>
>   <data>1</data>
>   <group>
>     <data>2</data>
>     <group>
>       <data>3</data>
>       <results>
>         <!-- put ancestor <data> values here, closest first -->
>       </results>
>     </group>
>   </group>
> </root>
>
> I wanted the lowest-level <results> element to contain all the ancestor
<data> values, in order of closest ancestor first. By applying reverse() to
the ancestor results, this gives the desired results of b321b:
>
>   <xsl:template match="results">  <!-- summarize <data> -->
>     <xsl:variable name="all-data" as="text()*"
select="reverse(ancestor::*/data/text())"/>
>     <xsl:copy>
>       <xsl:value-of select="$all-data"/>
>     </xsl:copy>
>   </xsl:template>
>
> But if I move the text() evaluation from the <xsl:variable> to the
<xsl:value-of>, then I get b123b instead:
>
>   <xsl:template match="results">  <!-- summarize <data> -->
>     <xsl:variable name="all-data" as="element()*"
select="reverse(ancestor::*/data)"/>
>     <xsl:copy>
>       <xsl:value-of select="$all-data/text()"/>
>     </xsl:copy>
>   </xsl:template>
>
> The cause is that the b/b in b$all-data/text()b XPath expression
causes the results to be sorted in document order. Somehow I thought that once
the elements were in the variable, they became disassociated with the source
document. But apparently theybre not, which updates my mental model.
>
> If I change b/b to the b!b operator (apply an operation to each item
in a sequence), then I get b321b again because the reversed ancestor order
is preserved:
>
>       <xsl:value-of select="$all-data ! text()"/>
>
> Anyway, just passing this along as a friendly reminder to the other novices
on the list. I spent more time than Ibd like to admit figuring this out on
my more complicated stylesheet.
>
> Chris
>
> P.S. MANY thanks to Martin for enabling me to fiddle my way to
understanding!
>
> -----
> Chris Papademetrious
> Tech Writer, Implementation Group
> (610) 628-9718 home office
> (570) 460-6078 cell
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3500899> (by
email <>)

Current Thread