RE: [xsl] xsl sort - 1 transform or 2

Subject: RE: [xsl] xsl sort - 1 transform or 2
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 4 Mar 2005 21:24:56 -0000
Sort changes the processing order of records, but it doesn't rearrange them
in the tree. So when you ask for the preceding-sibling of an element, you
get the element it was next to it the source, not the one that comes before
it in sorted order.

You'd be better off thinking of this as a grouping problem, and using
Muenchian grouping. Alternatively, do a sort first, then do the grouping in
a second pass using the technique you're attempting now.

Michael Kay
http://www.saxonica.com/

> -----Original Message-----
> From: Whitney, Dan (CanWest Interactive) 
> [mailto:DWhitney@xxxxxxxxxxx] 
> Sent: 04 March 2005 20:46
> To: 'mulberry - xsl'
> Subject: [xsl] xsl sort - 1 transform or 2
> 
> I am trying to accomplish the following transform (using 
> saxon 6.5.3) in 
> the following order:
> 1. sort by "exchange", then sort by "sort" within exchange
> 2. where an "exchange" <> the previous "exchange"  I want to 
> print above
> "name":
> @blockhead:"exchange"
> @block:"name"
> 3. where a record's "symbol" is the same as the previous 
> record's "symbol" 
> only output the initial record's "symbol"
>  
> Everything works as hoped when the sort isn't applied, but when it is
> applied 
> I get the @blockhead/@block printing above the same name 
> "Titanium..." and not above the name "AltaCda Enrg" as I was hoping. 
> I also don't get a consolidation the the symbols. 
> Do I have to do this in 2 stages - perform the sort as 1 xsl 
> and then do 
> the rest on the sorted xml output? or can I do it in a single 
> style sheet?
>  
> Here's the xml
>  
> <?xml version="1.0" encoding="iso-8859-1"?>
>  
> <publication>
> <document>
> <record fragment="blocktrades">
> <exchange>Toronto</exchange>
> <name>Thomson</name>
> <sort>Thomson Corporation 01TOC</sort>
> <time>13:30</time>
> <symbol>TOC</symbol>
> </record>
> <record fragment="blocktrades">
> <exchange>Toronto</exchange>
> <name>Abitibi-Cons</name>
> <sort>Abitibi Consolidated Incorporated 01A</sort>
> <time>11:25</time>
> <symbol>A</symbol>
> </record>
> <record fragment="blocktrades">
> <exchange>Toronto</exchange>
> <name>Petro-Canada</name>
> <sort>Petro Canada 01PCA</sort>
> <time>13:27</time>
> <symbol>PCA</symbol>
> </record>
> <record fragment="blocktrades">
> <exchange>Toronto</exchange>
> <name>Abitibi-Cons</name>
> <sort>Abitibi Consolidated Incorporated 01A</sort>
> <time>11:23</time>
> <symbol>A</symbol>
> </record>
> <record fragment="blocktrades">
> <exchange>TSX Venture</exchange>
> <name>Titanium</name>
> <sort>Titanium Corporation Incorporated 01TIC</sort>
> <time>13:26</time>
> <symbol>TIC</symbol>
> </record>
> <record fragment="blocktrades">
> <exchange>TSX Venture</exchange>
> <name>Omni-Lite</name>
> <sort>Omni Lite Industries Canada Incorporated 01OML</sort>
> <time>13:24</time>
> <symbol>OML</symbol>
> </record>
> <record fragment="blocktrades">
> <exchange>TSX Venture</exchange>
> <name>AltaCda Enrg</name>
> <sort>Altacanada Energy Corporation 01ANG</sort>
> <time>11:59</time>
> <symbol>ANG</symbol>
> </record>
> </document>
> </publication>
>  
> Here's the xsl
>  
> <xsl:stylesheet
>     version="1.0"
>     xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
>  
> <xsl:output
>     method="text"
>     encoding="iso-8859-1"
>     indent="yes"/>
>  
> 
> <xsl:variable name="tab" select="'&#009;'" />
> <xsl:variable name="nl" select="'&#10;'" />
>  
> 
> <xsl:template match="publication">
> <xsl:for-each select="document">
>   <xsl:for-each select="record">
>     <xsl:sort select="exchange" order="ascending"/>
>     <xsl:sort select="sort" order="ascending"/>
>     <xsl:choose>
>       <xsl:when test="position() = 1">
>         <xsl:text>@blockhead:</xsl:text>
>         <xsl:value-of select="exchange"/>
>         <xsl:value-of select="$nl"/>
>         <xsl:text>@block:</xsl:text>
>         <xsl:apply-templates/>
>       </xsl:when>
>       <xsl:when test="exchange = 
> preceding-sibling::record[1]/exchange">
>         <xsl:value-of select="$nl"/>
>         <xsl:apply-templates/>
>       </xsl:when>
>       <xsl:when test="exchange != 
> preceding-sibling::record[1]/exchange">
>         <xsl:value-of select="$nl"/>
>         <xsl:text>@blockhead:</xsl:text>
>         <xsl:value-of select="exchange"/>
>         <xsl:value-of select="$nl"/>
>         <xsl:text>@block:</xsl:text>
>         <xsl:apply-templates/>
>       </xsl:when>
>     </xsl:choose>
>   </xsl:for-each>
> </xsl:for-each>
> </xsl:template>
>     
> <xsl:template match="name">
>   <xsl:value-of select="."/>
> </xsl:template>
>  
> <xsl:template match="symbol">
>   <xsl:choose>
>     <xsl:when test=". = ../preceding-sibling::record[1]/symbol">
>       <xsl:value-of select="$tab"/>
>     </xsl:when>
>     <xsl:otherwise>
>       <xsl:value-of select="$tab"/>
>       <xsl:value-of select="."/>
>     </xsl:otherwise>
>   </xsl:choose>
> </xsl:template>
>  
> <xsl:template match="text()" />
> </xsl:stylesheet>
>  
> Here's the current output:
>  
> @blockhead:Toronto
> @block:Abitibi-Cons A
> Abitibi-Cons A
> Petro-Canada PCA
> AltaCda Enrg ANG
> Omni-Lite OML
> @blockhead:TSX Venture
> @block:Titanium TIC
>  
> and here's the desired output:
>  
> @blockhead:Toronto
> @block:Abitibi-Cons A
> Abitibi-Cons
> Petro-Canada PCA
> @blockhead:TSX Venture
> @block:AltaCda Enrg ANG
> Omni-Lite OML
> Titanium TIC
> 
> 
> And of course any help is greatly appreciated,
> Dan

Current Thread