[xsl] Sort of footnote nodes, processing and counting

Subject: [xsl] Sort of footnote nodes, processing and counting
From: "Trevor Nicholls" <trevor@xxxxxxxxxxxxxxxxxx>
Date: Mon, 27 Feb 2006 20:42:29 +1300

I am using XSL 2.0 (Saxon 8) to generate HTML files from XML data and have
problems with a <footnote> node type.

Before I detail the problems, here's the data model. The XML may contain
<footnote> nodes almost anywhere, and the HTML output which I am generating
needs to substitute some sort of flag "in-place" and include the footnote
content at the end of the high-level element which contains it. Some
footnotes are more local than others, and this is specified by an optional
'level' attribute on the footnote element.

   ...<footnote level="table">...</footnote>...
  <footnote level="document">...</footnote>

The 'level' attribute may be "document", "section", "table" or couple of
other high-level elements (and the DTD I am using ensures a default of

My XSL currently generates output in the right locations, but I can't get
precisely what I want.

The critical parts of the XSL:
<xsl:template match="/document">
  <title><xsl:value-of select="@title" /></title>
<h1><xsl:value-of select="@title" /></h1>
<xsl:apply-templates select="section" />
<xsl:call-template name="local_footnotes" />

<xsl:template match="section">
<xsl:variable name="depth" as="xs:integer">
  <xsl:value-of select="count(ancestor::section)+1" />
<xsl:element name="h{$depth}">
  <xsl:value-of select="@title" />
<xsl:apply-templates />
<xsl:call-template name="local_footnotes" />

<xsl:template name="local_footnotes">
<xsl:variable name="local" as="xs:string" select="name(.)" />
<xsl:if test="descendant::footnote[@level=$local]">
    select="descendant::footnote[@level=$local]" mode="footnote"/>

<xsl:template match="footnote">
<sup><xsl:number></sup>                <!--  LINE 1 -->

<xsl:template match="footnote" mode="footnote">
<xsl:apply-templates select="." />     <!-- LINE 2 -->
<xsl:apply-templates />

The line marked "LINE 1" is far too naive for my purposes; as it currently
stands most of the footnote numbers are duplicates because the numbering
restarts with every new parent element. However we'll return to this
expression later.

*My first problem*:
while I can generate a footnote number in-place with this template, the
attempt (at LINE 2) to repeat that number immediately before the footnote
proper is output fails with a stack overflow. I can't figure out what I am
doing wrong here (and when I searched the list archives for any ideas I saw
exactly this technique being used). So I'm stuck where to go next.

actually I want footnotes numbered (and formatted) differently in their
separate local sequences within document, section and table contexts. I
can't see that any suitable incantation for <xsl:number> exists to achieve
this in a single template, but I thought that if I cloned the footnote
template for each sequence then I might be able to do it, viz:
<xsl:template match="footnote[@level='document']">
<sup><xsl:number from="document" format="1"></sup>
<xsl:template match="footnote[@level='section']">
<sup><xsl:number from="section" format="a"></sup>
<xsl:template match="footnote[@level='table']">
<sup><xsl:number from="table" format="i"></sup>

This doesn't do the job, because the numbering still follows where the
footnote is, not whichever of my "high" levels the footnote belongs to. Next
I tried narrowing the count down, like so:
<xsl:template match="footnote[@level='document']">
<sup><xsl:number count="footnote[@level='document']" from="document"
<xsl:template match="footnote[@level='section']">
<sup><xsl:number count="footnote[@level='section']" from="section"
<xsl:template match="footnote[@level='table']">
<sup><xsl:number count="footnote[@level='table']" from="table"

This changes some of the numbers but they are still wrong (and if anything
they are *more* wrong!)

Can somebody please help put me back on the right track here?


Current Thread