[xsl] Fun with xsl:number and a key

Subject: [xsl] Fun with xsl:number and a key
From: JBryant@xxxxxxxxx
Date: Thu, 14 Oct 2004 12:55:13 -0500
Hi, all,

First, a disclaimer of sorts: This question is a matter of curiousity and 
expanding my understanding of XSL. The stylesheet I have works to my 
satisfaction, and my customers love the output, so all is well. But I am, 
as ever, curious about how things work.

If you've been following the "Better way to change context" thread, you've 
seen that I have trouble with getting xsl:number to work with a key. I 
thought I'd make a new topic, as we have gotten away from the issue of 
setting context.

I only have three lines in my XSL file that refer to the refentries key. 
The three lines are the definition and two places that I use it in the ref 
template. Here are those bits:

The key definition:
  <xsl:key name="refentries" match="@title" use="."/>

The ref template (trimmed a bit):
  <xsl:template match="ref">
    <xsl:variable name="thisChapter">
      <xsl:for-each select="key('refentries', .)">
        chapter<xsl:value-of 
select="substring-before(substring-after(saxon:path(), 'chapter['), 
']')"/>.html#
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="thisTest">
      <xsl:for-each select="key('refentries', .)">
        <xsl:number level="multiple"/>
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="reftarget" select="key('refentries', .)" />
    <xsl:value-of select="$thisTest"/><a href="{concat($thisChapter, 
generate-id($reftarget))}"><xsl:value-of select="."/></a>
  </xsl:template> <!-- match="ref" -->

And here's an XML file:
<book title="somebook">
  <chapter title="Introduction">
    <paragraph>Intro stuff</paragraph>
    <paragraph><ref>Getting Started</ref></paragraph>
  </chapter>
  <chapter title="Getting Started">
    <paragraph>Getting started stuff</paragraph>
    <paragraph><ref>Introduction</ref></paragraph>
  </chapter>
</book>

Here is the (extensively snipped) HTML output for chapter1:
  <h1 class="center">Chapter 1<br>Introduction</h1>
  <p>Intro stuff</p>
  <p>1<a href="chapter2.html#d1e19a1993">Getting Started</a></p>
  <h1><a name="d1e12a1993"></a>Some Topic</h1>
  <p>Some topic stuff</p>

Here is the (extensively snipped) HTML output for chapter2:
  <h1 class="center">Chapter 2<br>Getting Started</h1>
  <p>Getting started stuff</p>
  <p>1<a href="chapter1.html#d1e3a1993">Introduction</a></p>
  <p>1<a href="chapter1.html#d1e12a1993">Some Topic</a></p>

The relevant bit is the 1 before each <a> element. It should not always be 
1.

My question is this: Why does the following bit not generate a multi-level 
number?
      <xsl:for-each select="key('refentries', .)">
        <xsl:number level="multiple"/>
      </xsl:for-each>

Personally, I speculate that the cause is the nature of the key, which 
matches an attribute and then uses . If I understand correctly, this key 
holds the text of the attribute, which ditches the context information. 
Still, I would like to be sure that that's what's happening. I am also 
curious as to why, given the same information, saxon:path() gets the path 
and xsl:number doesn't.

Thanks to David Carlisle for ideas so far.

Jay Bryant
Bryant Communication Services

Current Thread