Re: [xsl] sorting and grouping - can't get it to work

Subject: Re: [xsl] sorting and grouping - can't get it to work
From: tcn@xxxxxxxxxxxxx (Trevor Nash)
Date: Mon, 02 Jul 2001 09:57:27 GMT
Hello Andreas

>Hello all,
>this is my last attempt to get some reaction to my question - previous
>attempts to post to this list did not give me any reactions - I did not even
>see my own posting to the list, perhaps this is normal (though when I
>answered someones post I got my post back from the list). But I also did not
>get any answer so I suspect my postings did never arrive.
If you are properly signed up to the list you will see this twice.  I
do not recall seeing this question before.

>Now for my question
>I have a little problem with data I want to sort and then place into a
>two-column table 
>(two of the sorted data items in each row).
>I am a XML/XSL-Newbie so please forgive me if I ask a too simple question
>for you experts.
>Here is my problem in detail - I hope I provided all the info you need.
This is good apart from the typo which Chris pointed out: you say this
part is working, so I am sure you really have match="data" in the
first template.

Your problem is that you need to wrap a <tr>...</tr> element around
each *pair* of items in the sorted result.  Unfortunately XSLT only
gives you access to the current node in a node list, you cannot see
current+1.  You might think following-sibling would do it, but this
operates on the original document order, not the sorted order.

I think Xalan C has the function node-set() ?  If so, the way out is

Get the sorted items into a variable by putting a xsl:for-each and
xsl:sort inside an xsl:variable.  Think of this variable as a new
document containing a copy of every <item> element, in sorted order.

Now apply the code you have already written to get a two-column layout
to the variable.  You will need to say select="xx:node-set($var)"
instead of just select="$var", and you will need to check your
documentation to see what 'xx' has to be and what else you might have
to do when calling extension functions.

following-sibling now does what you want, because the 'document' is
now the sorted tree stored in the variable, not the original document.

In the context of the code you posted:

First, I am not sure what Xalan-C needs, but you probably need to add
a namespace declaration to the xsl:stylesheet.

><xsl:template match="data/item">
This should be "data".

Here, use xsl:variable to make a sorted copy of the input items.  You
might need xsl:copy-of.

>    <table>
>        <xsl:for-each select="item[position() mod 2 = 1]">
Change this to
    <xsl:for-each select="$var/item[position() mod 2 = 1]">
>            <tr>
>                <xsl:apply-templates select=". |
>                <xsl:if test="not(following-sibling::item[position()=1])">
>                    <td>&nbsp;</td>
>                </xsl:if>
>            </tr>
>        </xsl:for-each>
>    </table>
><xsl:template match="item">
>	<td><xsl:value-of select="name"/></td>

I have deliberately not given you a complete solution - working
through it will help you next time you need to do something similar.
i am doing it for free too ;-)

Hope this helps,

Trevor Nash
Traditional training & distance learning,
Consultancy by email

Melvaig Software Engineering Limited
voice:     +44 (0) 1445 771 271 
email:     tcn@xxxxxxxxxxxxx

 XSL-List info and archive:

Current Thread