|
Subject: Re: [xsl] Making a Table of Alphabetized Strings grouped by First Letter From: Joerg Pietschmann <joerg.pietschmann@xxxxxx> Date: Thu, 31 Jan 2002 17:05:51 +0100 |
Elizabeth Barham <soggytrousers@xxxxxxxxx> wrote:
[about a grouping problem]
Here is a pure XSLT 1.0 solution. It's somewhat convoluted, a
solution in XSLT 2.0 or using xx:node-set() could get rid
of recursion and the Piez-Method for simulating iteration
and would therefore probably easier to read.
I used a simplified XML
<?xml version="1.0"?>
<counties>
<county>Anderson</county>
<county>Bailey</county>
...
</counties>
in order to shorten the XPath, they are already unwieldy enough.
The core is the recursive template which accumulates both county
elements with all different initials in "$startlist" and the
maximum number of counties starting with a particular initial
in "$maxcount".
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:key name="county-initial" match="county" use="substring(.,1,1)"/>
<xsl:template match="counties">
<table>
<xsl:call-template name="accumulate">
<xsl:with-param name="countylist" select="county"/>
<xsl:with-param name="startlist" select="/.."/>
<xsl:with-param name="maxcount" select="0"/>
</xsl:call-template>
</table>
</xsl:template>
<xsl:template name="accumulate">
<xsl:param name="countylist"/>
<xsl:param name="startlist"/>
<xsl:param name="maxcount"/>
<xsl:choose>
<xsl:when test="$countylist">
<xsl:variable name="initial" select="substring($countylist[1],1,1)"/>
<xsl:variable name="currentcount"
select="count(key('county-initial',$initial))"/>
<xsl:choose>
<xsl:when test="$currentcount > $maxcount">
<xsl:call-template name="accumulate">
<xsl:with-param name="countylist" select="$countylist[not(substring(.,1,1)=$initial)]"/>
<xsl:with-param name="startlist" select="$startlist|$countylist[1]"/>
<xsl:with-param name="maxcount" select="$currentcount"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="accumulate">
<xsl:with-param name="countylist" select="$countylist[not(substring(.,1,1)=$initial)]"/>
<xsl:with-param name="startlist" select="$startlist|$countylist[1]"/>
<xsl:with-param name="maxcount" select="$maxcount"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- use Wendell Pietz' method for iterating over 1..$maxcount -->
<xsl:for-each select="(//node())[position() <= $maxcount]">
<xsl:variable name="index" select="position()"/>
<tr>
<xsl:for-each select="$startlist">
<xsl:for-each select="key('county-initial',substring(.,1,1))[$index]">
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</xsl:for-each>
</tr>
</xsl:for-each>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
As the lists auto documentation demon seems to be down, ask
again if something is unclear or too tricky.
HTH
J.Pietschmann
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
| Current Thread |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] Making a Table of Alphabetize, Elizabeth Barham | Thread | [xsl] XSLT trace, Oliver Becker |
| RE: [xsl] child numbering, Michael Kay | Date | AW: [xsl] xsl:sort/@case-order feat, Nestel, Frank ISC 6 |
| Month |