Re: [xsl] Combining grouping and generate-id() for multilevel TOC

Subject: Re: [xsl] Combining grouping and generate-id() for multilevel TOC
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 18 Jul 2001 10:19:31 +0100
Hi Armin,

> Am I correct if I assume that I need to
> 1. add a second grouping in the xsl for that second level, like I
> did for the first one, and
> 2. use another generate-id() to refer to all these second level
> groups with a unique anchor?

Yes, that's right. You've declared the keys correctly, first to group
the Bug elements by their Category1 child, and then to group them
within that by their Category1+Category2 children:

> <xsl:key name="categories" match="Bug" use="Category1"/>
> <xsl:key name="categories2" match="Bug"
>          use="concat (Category1, ' ',Category2)" />

Now when you generate your table of contents, for the Category1
headings you select the first Bug element with a particular Category1
element. To create the Category2 headings, you need to select the
first Bug element with a particular combination of
Category1+Category2:

  <p><b>Table of Contents</b></p>
  <p>
  <xsl:for-each select="//Bug[generate-id() =
                              generate-id(key('categories',
                                              Category1)[1])]">
    <a href="#cat1{generate-id()}">
      <xsl:value-of select="Category1" />
    </a>
    <br />
    <xsl:for-each
        select="key('categories', Category1)
                     [generate-id() =
                      generate-id(
                         key('categories2',
                             concat(Category1, ' ', Category2))[1])]">
      <a href="#cat2{generate-id()}">
        <xsl:value-of select="Category2" />
      </a>
    </xsl:for-each>
  </xsl:for-each>

When you come to building up the *content*, you'll probably find it
easiest to use moded templates. You can apply templates in 'Category1'
mode to the Bugs with unique Category1s to create the Category1
headings, and in Category2 mode to create the Category2 headings:

<xsl:template match="Bugs">
  <xsl:apply-templates mode="Category1"
    select="Bug[generate-id() =
                generate-id(key('categories', Category1)[1])]" />
</xsl:template>

<xsl:template match="Bug" mode="Category1">
  <div>
    <b>
      <a name="cat1{generate-id(.)}">
        <xsl:value-of select="Category1" />
      </a>
    </b>
  <div>
  <xsl:apply-templates mode="Category2"
    select="key('categories', Category1)
                 [generate-id() =
                  generate-id(
                     key('categories2',
                         concat(Category1, ' ', Category2))[1]" />
</xsl:template>

Change the following template to give the heading style that you want
for the Category2 headings.

<xsl:template match="Bug" mode="Category2">
  <div>
    <a name="cat2{generate-id(.)}">
      <xsl:value-of select="Category2" />
    </a>
  <div>
  <xsl:apply-templates
      select="key('categories2', concat(Category1, ' ', Category2))" />
</xsl:template>

And add a template matching Bug elements in the default mode to give
the content (i.e. applying templates to the Calls in the BugBase).

I hope that helps,

Jeni

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


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


Current Thread