Re: [xsl] Creating a hierarchical table of contents using xsl:number

Subject: Re: [xsl] Creating a hierarchical table of contents using xsl:number
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Tue, 16 Feb 2010 15:38:02 -0500
Hi Martin,

To add to what Syd says:

You don't want to use the @value attribute on xsl:number. It isn't what you want, and it is getting in the way.

No, you don't need the for-each. Actually, how you select and process the nodes -- whether by way of xsl:apply-templates or for-each or what have you, is entirely immaterial to what number is generated and how it comes out.

Like Syd, I recommend Mike Kay's treatment. Additionally, I recommend spending a few minutes playing with a minimal test case (such as what you posted us). Start with xsl:number, then add @count, @level, @from and @format attributes to see what they do. Keep in mind that the calculation of the number by xsl:number is always done by examining the placement of the current node in its tree -- unless, that is, you override it by putting @value on there, which is probably what's accounting for your problems.


At 03:17 PM 2/16/2010, you wrote:
I think you may be working too hard, and that the following will do
what you want:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="";

<xsl:output indent="yes" method="xml"/>

  <xsl:template match="/">
      <xsl:apply-templates select="//level1 | //level2 | //level3"/>

<xsl:template match="level1|level2|level3">
<xsl:number level="multiple" count="level1|level2|level3" format="1.1. "/>
<xsl:value-of select="@title"/><br/><xsl:text>&#x0A;</xsl:text>


It is worth reading the discussion of <xsl:number> in a worthwhile reference (I use Kay's) a few times, and playing around with it.

Martin Jackson writes:
> I'm trying to create a table of content that looks like this:
> 1. Fruit
> 1.1. Citrus
> 1.1.1. Orange
> 1.1.2. Lemon
> 1.1.3. Lime
> 1.2. Apple
> 2. Vegetables
> 2.1. Tomato
> 2.2. Carrot
> from an xml file with this structure
> <level1 title="fruit">
> <level2 title="citrus">
> <level3 title="orange"/>
> <level3 title="lemon"/>
> <level3 title="lime"/>
> </level2>
> <level2 title="apple"/>
> </level1>
> <level1 title="vegetables">
> <level2 title="tomato"/>
> <level2 title="carrot"/>
> But I can't figure out how to make my xsl transformation write the
> numbers for all the levels in the hierarchy. Right now it just outputs
> the bottom level, so it looks like this:
> 1. Fruit
> 1. Citrus
> 1. Orange
> 2. Lemon
> 3. Lime
> 2. Apple
> 2. Vegetables
> 1 Tomato
> 2 Carrot
> This is what my code looks like:
> <xsl:for-each select="level1">
> <xsl:number level="multiple" count="h1" value="position()" format="1.1. "/>
> <xsl:value-of select="@title"/><br />
> <xsl:for-each select="level2">
> <xsl:number level="multiple" count="h1|h2" value="position()" format="1.1. "/>
> <xsl:value-of select="@title"/><br />
> <xsl:for-each select="level3">
> <xsl:number level="multiple" count="h1|h2|h3" value="position()"
> format="1.1. "/>
> <xsl:value-of select="@title"/><br />
> </xsl:for-each>
> </xsl:for-each>
> </xsl:for-each>
> From some stuff I have read I have gathered that this probably should
> be possible to solve without nested for-each-loops, with just one
> <xsl:number> tag having correctly formulated attributes. But for
> reasons hard to explain, right now I need to solve this using
> for-each.
> So I have two questions:
> 1. Is it possible to solve it using roughly the structure I have now,
> with the for-each-loops, and how would I do that?
> 2. If that code structure is unnecessarily complicated (which I
> suspects it is), what would be a more optimal way of achieving the
> same result (still using xsl:number)?
> Regards,
> Martin Jackson

Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.      
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
  Mulberry Technologies: A Consultancy Specializing in SGML and XML

Current Thread