This is the mail archive of the
xsl-list@mulberrytech.com
mailing list .
Re: Muenchian method, and keys 'n stuff
- From: Jeni Tennison <jeni at jenitennison dot com>
- To: xsl-list at lists dot mulberrytech dot com
- Date: Tue, 22 Jan 2002 13:51:42 +0000
- Subject: Re: [xsl] Muenchian method, and keys 'n stuff
- Organization: Jeni Tennison Consulting Ltd
- References: <9B66BBD37D5DD411B8CE00508B69700FE7AA8B@pborolocal.rnib.org.uk>
- Reply-to: xsl-list at lists dot mulberrytech dot com
Hi Dave,
> but I can't figure out a way of iterating over an alphabet, and
> processing the records to 'announce' the missing letters (i.e. no
> books beginning with that letter)
I'd just iterate over the alphabet held in a string, with a recursive
template. It starts off with the whole alphabet and gradually whittles
it down letter by letter until there's no alphabet left:
<xsl:template name="alphabetical">
<xsl:param name="alphabet" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:if test="$alphabet != ''">
<xsl:variable name="letter"
select="substring($alphabet, 1, 1)" />
... do things with the letter ...
<xsl:call-template name="alphabetical">
<xsl:with-param name="alphabet"
select="substring($alphabet, 2)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
In your case, the thing you want to do with the letter is identify
those r elements whose Ra/lett is that letter. You can do this with
the key that you've made, as follows:
<xsl:template name="alphabetical">
<xsl:param name="alphabet" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:if test="$alphabet != ''">
<xsl:variable name="letter"
select="substring($alphabet, 1, 1)" />
<xsl:variable name="auths"
select="key('auth', $letter)" />
<xsl:choose>
<xsl:when test="$auths">
<h2>
The letter
<xsl:value-of select="translate($letter, $l, $u)" />
</h2>
<xsl:for-each select="$auths">
<h3><xsl:value-of select="Ra/au" /></h3>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<p>
There are no authors beginning with
<xsl:value-of select="$letter" />
</p>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="alphabetical">
<xsl:with-param name="alphabet"
select="substring($alphabet, 2)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
To call the template, all you need is:
<xsl:call-template name="alphabetical" />
Note that the key will give you all r elements with the same Ra/lett,
and as such it won't be scoped within the 'adventure'. To get the
scoping, you need to do one of the following:
- include the adventure's (generated) ID within the key, and pass
that ID to the alphabetical template
- don't use the key to retrieve the rs with a particular Ra/lett,
just use r[Ra/lett = $letter] instead (less efficient than a key,
probably)
Cheers,
Jeni
---
Jeni Tennison
http://www.jenitennison.com/
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list