This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Adjusting sorted list
- From: Dimitre Novatchev <dnovatchev at yahoo dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Thu, 16 May 2002 07:58:21 -0700 (PDT)
- Subject: [xsl] Re: Adjusting sorted list
- Reply-to: xsl-list at lists dot mulberrytech dot com
> I have the following XML:
> <a>
> <b>4</b>
> <b>9</b>
> <b>6</b>
> <b>1</b>
> <b>8</b>
> <b>6</b>
> <b>4</b>
> <b>7</b>
> </a>
>
> I am trying to generate the following ouput:
> <a>
> <b rank="1">1</b>
> <b rank="2">4</b>
> <b rank="2">4</b>
> <b rank="3">6</b>
> <b rank="3">6</b>
> <b rank="4">7</b>
> <b rank="5">8</b>
> <b rank="6">9</b>
> </a>
>
> Using xsl:for-each with a sort on b and then using position() I can
> get a ranking from 1 to 8 but I have no idea how to achieve the
above.
>
> I have dug around in the archives for some ideas but to no avail.
> I see that I can't use a variable and adjust it's value with each
> iteration (as it's not actually iterating).
> I have also looked into using a recursive named template but am not
> sure how to achieve the above and sort the output???
This is a grouping problem. You have to take just the elements with
distinct values -- their positions in the node-list will determine the
rank. Then for each such distinct element you have to produce all other
elements with the same value -- and to assign to them the same rank.
Bellow is the stylesheet that does this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kRanking" match="b" use="."/>
<xsl:template match="/">
<a>
<xsl:for-each select="/a/b[generate-id()
=
generate-id(key('kRanking',.)[1])
]">
<xsl:sort select="." data-type="number"/>
<xsl:variable name="vPos" select="position()"/>
<xsl:for-each select="key('kRanking',.)">
<b rank="{$vPos}">
<xsl:value-of select="."/>
</b>
</xsl:for-each>
</xsl:for-each>
</a>
</xsl:template>
</xsl:stylesheet>
With your source xml it produces exactly the desires result:
<a>
<b rank="1">1</b>
<b rank="2">4</b>
<b rank="2">4</b>
<b rank="3">6</b>
<b rank="3">6</b>
<b rank="4">7</b>
<b rank="5">8</b>
<b rank="6">9</b>
</a>
Hope this helped.
Cheers,
Dimitre Novatchev.
__________________________________________________
Do You Yahoo!?
LAUNCH - Your Yahoo! Music Experience
http://launch.yahoo.com
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list