[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Grouping while sorting

Subject: Re: [xsl] Grouping while sorting
From: "Ragulf Pickaxe" <jawxml@xxxxxxxxxxx>
Date: Mon, 22 Nov 2004 11:18:53 +0000
xsl sort two sorts
Hello again,

I have looked at Jeni's solution, and I would very much like to implement this solution.
Unfortunately, I am not good enough with keys yet, and my problem is a little more complicated than my first example.


I will try to scetch a more complicated problem, and I hope that someone can show me how to this can be solved.
I do not know if one pass is possible in XSLT 1.0....?


Again my thanks for anybody who takes the time to look at this.

Regards,
Ragulf Pickaxe


<!-- Data before first pass in two-pass solution --> <?xml version="1.0"> <Root> <Elem GroupID="A" Type1="1" Type2="0" Order="7">A7</Elem> <Elem GroupID="A" Type1="1" Type2="0" Order="5">A5</Elem> <Elem GroupID="B" Type1="0" Type2="0" Order="4">B4</Elem> <Elem GroupID="D" Type1="0" Type2="1" Order="2">D2</Elem> <Elem GroupID="C" Type1="1" Type1="1" Order="4">C4</Elem> <Elem GroupID="B" Type1="0" Type2="0" Order="3">B3</Elem> <Elem GroupID="A" Type1="1" Type2="0" Order="2">A2</Elem> <Elem GroupID="C" Type1="1" Type1="1" Order="1">C1</Elem> <Elem GroupID="D" Type1="0" Type2="1" Order="4">D4</Elem> <Elem GroupID="B" Type1="0" Type2="0" Order="2">B2</Elem> <Elem GroupID="D" Type1="0" Type2="1" Order="3">D3</Elem> <Elem GroupID="A" Type1="1" Type2="0" Order="1">A1</Elem> </Root>


<!-- Data after first pass in two-pass solution (sorted by @GroupID and @Order) -->
<?xml version="1.0">
<Root>
<Elem GroupID="A" Type1="1" Type2="0" Order="1">A1</Elem>
<Elem GroupID="A" Type1="1" Type2="0" Order="2">A2</Elem>
<Elem GroupID="A" Type1="1" Type2="0" Order="5">A5</Elem>
<Elem GroupID="A" Type1="1" Type2="0" Order="7">A7</Elem>
<Elem GroupID="B" Type1="0" Type2="0" Order="2">B2</Elem>
<Elem GroupID="B" Type1="0" Type2="0" Order="3">B3</Elem>
<Elem GroupID="B" Type1="0" Type2="0" Order="4">B4</Elem>
<Elem GroupID="C" Type1="1" Type1="1" Order="1">C1</Elem>
<Elem GroupID="C" Type1="1" Type1="1" Order="4">C4</Elem>
<Elem GroupID="D" Type1="0" Type2="1" Order="2">D2</Elem>
<Elem GroupID="D" Type1="0" Type2="1" Order="3">D3</Elem>
<Elem GroupID="D" Type1="0" Type2="1" Order="4">D4</Elem>
</Root>



<?xml version="1.0"> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:param name="ChooseWhichType1First" select="'1'"/> <xsl:template match="/"> <Output> <xsl:apply-templates select="Root"/> </Output> </xsl:template>

<xsl:template match="Root">
<!-- The different types of Elem have to be in a certain order - independent of GroupID -->
<xsl:apply-templates select="Elem[@Type1=$ChooseWhichType1First]"/>
<xsl:apply-templates select="Elem[not(@Type1=$ChooseWhichType1First)][Type2='1']"/>
<xsl:apply-templates select="Elem[not(@Type1=$ChooseWhichType1First)][Type2='0']"/>
<!-- In the two-pass solution I do not have to sort with the two sorts below: -->
<!--
<xsl:sort select="@GroupID">
<xsl:sort select="@Order" data-type="number">
-->
<!-- I have an idea that I will need one key for each of the above templates, but I do not know what to write, nor whether


my idea is even right (Jeni Tennison's solution provided at buttom of this mail) -->
</xsl:template>


<xsl:template match="Elem">
 <xsl:if test="not(preceding-sibling::Elem/@GroupID=current()/@GroupID)">
   <Group><xsl:value-of select="@GroupID"/></Group>
 </xsl:if>
 <xsl:value-of select="."/> -
</xsl:template>
</xsl:stylesheet>


Output: <Output> <Group>A</Group>A1 - A2 - A5 - A7 - <Group>C</Group>C1 - C4 - <Group>D</Group>D2 - D3 - D4 - <Group>B</Group>B2 - B3 - B4 - </Output>


(Summary: I would very much like to get the same output in one go with the unsorted input (the first pass) - if this is


possible).

Jeni Tennison's solution, which would if there was no @Type1 and @Type2 to consider:
<xsl:key name="elems" match="Elem" use="@GroupID" />


<xsl:template match="Root">
 <xsl:for-each select="Elem[generate-id(.) =
                            generate-id(key('elems', @GroupID)[1])]">
   <Group><xsl:value-of select="@GroupID" /></Group>
   <xsl:for-each select="key('elems', @GroupID)">
     <xsl:sort select="@Order" data-type="number" />
     <xsl:value-of select="." /> -
   </xsl:for-each>
 </xsl:for-each>
</xsl:template>

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.