xsl-list
[Top] [All Lists]

Re: Grouping while sorting

2004-11-22 04:18:53
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[(_at_)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/


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



<Prev in Thread] Current Thread [Next in Thread>