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

Re: [xsl] Grouping while sorting


Subject: Re: [xsl] Grouping while sorting
From: "M. David Peterson" <m.david@xxxxxxxxxx>
Date: Sun, 21 Nov 2004 10:52:32 -0800

Your best bet is to take the problem and break it into two seperate processes.

In the first process create a variable and within the opening and closing brackets of that variable put the logic you are using to sort your elements as desired. This process is often refered to as creating a temporary tree. In strict XSLT 1.0 the problem with this method is that there is no way to tree the Result Tree Fragment (RTF) and a node-set and as such each vendor has implemented similar but just slightly different (just enough to make each implementation non-portable between processors) such that without knowing which processor you are using I can give you the specifics of the syntax for the node-set function particular to that processor. A while back Jeni Tennison and company started the EXSLT project which is an effort to bring further functionality to XSLT using standard function names within one particular namespace extension library. There are several processors that support the EXSLT extensions directly the most notable being Dr. Michael Kay's Saxon processor. You can learn more about EXSLT at EXSLT.org, continue your learning of XSLT through Jeni Tennisons XSL tutorials (http://www.jenitennison.com), and download the latest build of Saxon from Dr. Kay's company site (http://www.saxonica.com). All this aside you can look up the specifics to the variation on the node-set function implemented by your processor by simply looking inside the documentation.

With this variable you can then, via the node-set function, treat the resulting XML node-set just like any node-set. The document order for this node-set is now in sorted order based on your original sort criteria. As such you can expect that whatever sort process you place on this newly order node-set the result will be based on the new document order and not the original document order, which at this point in the transformation processor the processor will know nothing about as it sees a brand new node-set that has no direct relation to the originating node-set///

Hope this helps!

<M:D/>

Ragulf Pickaxe wrote:

Hello all,

I seem to be caught on trying to sort something while at the same time grouping them.
In the first input (see below), I have no problems, but the second gives me problems in the current solution.


The problem seems that I get the nodes in sorted order, but the test on the previous sibling goes to the document order.
How do I make the test so that I can group these elements, and still retain the sorted order?


Thank you very much in advance!
Ragulf Pickaxe

<?xml version="1.0">
<Root> <!-- Input 1 -->
 <Elem GroupID="A" Order="1">A1</Elem>
 <Elem GroupID="A" Order="2">A2</Elem>
 <Elem GroupID="B" Order="4">B4</Elem>
 <Elem GroupID="A" Order="5">A5</Elem>
 <Elem GroupID="C" Order="1">C1</Elem>
 <Elem GroupID="B" Order="7">A7</Elem>
</Root>


<?xml version="1.0"> <Root> <!-- Input 2 --> <Elem GroupID="A" Order="7">A7</Elem> <Elem GroupID="A" Order="5">A5</Elem> <Elem GroupID="B" Order="4">B4</Elem> <Elem GroupID="A" Order="2">A2</Elem> <Elem GroupID="C" Order="1">C1</Elem> <Elem GroupID="B" Order="1">A1</Elem> </Root>



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

<xsl:template match="Root">
 <xsl:apply-templates select="Elem">
   <xsl:sort select="@GroupID">
   <xsl:sort select="@Order" data-type="number">
 </xsl:apply-templates>
</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 from input 1: <Output> <Group>A</Group>A1 - A2 - A5 - A7 - <Group>B</Group>B4 - <Group>C</Group>C1 - </Output>

Output from input 2
<Output>
 A1 - A2 - A5 - <Group>A</Group>A7 -
 <Group>B</Group>B4 -
 <Group>C</Group>C1 -
</Output>

(Summary: I would very much like to get second output to be the same as the first output - I hope that this is possible).

_________________________________________________________________
Don't just search. Find. Check out the new MSN Search! http://search.msn.com/


Current Thread
Keywords