This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: sorting and grouping - can't get it to work
- To: xsl-list at lists dot mulberrytech dot com
- Subject: Re: [xsl] sorting and grouping - can't get it to work
- From: tcn at melvaig dot co dot uk (Trevor Nash)
- Date: Mon, 02 Jul 2001 09:57:27 GMT
- Cc: Andreas Waechter <A dot Waechter at logics dot de>
- Organization: Melvaig Software Engineering Limited
- References: <585E20EB9093524CADB69E736A3F57102D4E70@r2d2.logics.de>
- Reply-To: xsl-list at lists dot mulberrytech dot com
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
this:
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=". |
>following-sibling::item[position()=1]"/>
> <xsl:if test="not(following-sibling::item[position()=1])">
> <td> </td>
> </xsl:if>
> </tr>
> </xsl:for-each>
> </table>
></xsl:template>
>
><xsl:template match="item">
> <td><xsl:value-of select="name"/></td>
></xsl:template>
>
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@melvaig.co.uk
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list