Re: [xsl] Muenchian method, and keys 'n stuff

Subject: Re: [xsl] Muenchian method, and keys 'n stuff
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Wed, 23 Jan 2002 10:19:07 +0000
Hi Dave,

>> To be more explicit about the solution I was suggesting for that -
>> make the key include the ID for the adventure as well as the Ra/lett:
>> 
>> <xsl:key name="auth" match="adventure/r"
>>          use="concat(generate-id(..), ' ', Ra/lett)" />
>> 
>> The key values here are combinations of the ID of the adventure and
>> the letter that the author's name starts with. I used a space between
>> them as a separator, but you could use anything that isn't allowed in
>> an ID.
>
> I did try that, without results,
> though I didn't have a seperator. Is that essential?

It probably isn't essential in this case, given that Ra/lett will
always be one letter long. But it's good practice in the general case,
whenever you're creating a key value that's a combination of multiple
values.

> I want something like
>
> 'Adventure'
>   Adrews, Fred
>    All books by Andrews, Fred
>   Axminster, Joe
>    All books by him (no author)
>
> Hence the find the first, process the rest as following-siblings::r
> method.

...OK. So actually you have two levels of grouping:

  - group by letter (to enable you to work out which letters don't
    have authors)
  - group by author

And both of the groupings occur within a particular section. And the
'adventure' element is actually giving the name of the section, right?
I thought that all the section elements were called 'adventure' (for
some reason). So you could use the name of the element around the r
elements to give you the 'id', rather than generating one.

Can I assume that the Ra/lett gives the first letter of the author's
name? If so, you don't need to do the normal thing of having the
second-level key incorporate the information from the first-level key,
because you'll never get two rs with the same author name but
different Ra/letts.

So I think that you need two keys. The first that groups in sections
by letter:

<xsl:key name="books-in-section-by-letter"
         match="r"
         use="concat(name(..), ' ', Ra/lett)" />

The second groups in sections by author:
         
<xsl:key name="books-in-section-by-author"
         match="r"
         use="concat(name(..), ' ', Ra/auth)" />

You iterate over the various letters, and get all the authors in the
current section (assuming that the template is called when the current
node is the section element) with:

  <xsl:variable name="books"
                select="key('books-in-section-by-letter',
                            concat(name(), ' ', $letter))" />

Then you test whether there are any books with that letter, so you can
send the message when there aren't:

  <xsl:choose>
    <xsl:when test="$books">
      ...
    </xsl:when>
    <xsl:otherwise>
      No books beginning with <xsl:value-of select="$letter" />
    </xsl:otherwise>
  </xsl:choose>

Within the xsl:when is where you need to apply templates to the books
with unique authors, as follows:

  <xsl:apply-templates
    select="$books[generate-id() =
                   generate-id(key('books-in-section-by-author',
                                   concat(name(), ' ', Ra/auth))[1])]" />

>> > Strange, that keys have been given only the current document as
>> > scope, I can't use them across n documents, I can't use them in a
>> > section of a document... I'm sure there are other use cases for
>> > limited scope keys. Feature for consideration for 2.0?
>> 
>> It does seem to be a very popular use. I should think that most of the
>> utility comes when using the Muenchian grouping method. But the above
>> case (which doesn't really use Muenchian grouping, because you *know*
>> what groups you're after) illustrates that it's useful elsewhere.
>
> I chose it to get the first, rest style of processing.
>
> What do you think of extending the use of keys to a specific scope?

Err... that's what I was talking about :) Retrieving the items from a
key within a specific node seems to be quite frequently required, but
I'm not sure whether that's just because we're using Muenchian
grouping a lot. When we start using XSLT 2.0 grouping, then the
requirement will be a lot less, I think.

[I'm going to send an XSLT 2.0 solution to the above problem in a
separate mail...]

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread