[xsl] giving key() a context (changes between XSLT 1.0 and 2.0)

Subject: [xsl] giving key() a context (changes between XSLT 1.0 and 2.0)
From: Joseph Dane <jdane@xxxxxxxxxx>
Date: Thu, 02 Sep 2004 15:30:00 -1000
Greetings -

I've just started using key() to find items in a lookup table stored
directly in the stylesheet.  I have Mike Kay's XSLT 2.0 book, but for
this particular project I'm restricted for now to XSLT 1.0.

I found several descriptions of using for-each as a hack to change
the context node for the invocation of key(), as in:

<xsl:stylesheet ...>

  <config xmlns='http://hawaii.edu/netdb'>
    <page id='listlocs'>
      <search-title>Search Locations</search-title>
      <search-url>searchlocs.x</search-url>
    </page>
    ...
  </config>

  <xsl:key name='page-config' 
	   match='netdb:page'
	   use='@id'/>
  
  <xsl:variable name='config' 
		select='document("")/*/netdb:config'/>

  <xsl:template ...>
    ...
    <xsl:for-each select='$config'>
      <xsl:value-of select='key("page-config", $pageid)/netdb:search-url'/>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

which works well enough.

I also noticed that in XSLT 2.0, the key() function can take an
optional third argument, which will do away with the need for the
for-each thing.

But (and here's where I get to my question) the book also includes
something like this:

 <xsl:variable name='biogs' select='...'/>

 <xsl:template ...>

    ...
    <xsl:variable name='auth' select='$biogs/key("biog", $name)'/>
    ...

 </xsl:template>

That is, key() is used directly in the expression, and has its
context supplied by the previous expression step.  Assuming I'm
understanding all this correctly, then I like this approach more than
the three arg key() call, because it seems to fit better with
typical XSLT usage patterns.

The above, however, didn't work in my XSLT 1.0 processor.  No
surprise, I guess.  No need for the for-each hack if you could do
that.  But I've been looking around for a succint explaination of
what exactly changed in XSLT 2.0 to make this possible, and I haven't
been able to find it yet.  

So I guess my questions are:

 * is it true that the above ($biogs/key( ...)) really is illegal in
   XSLT 1.0?

 * what restriction was relaxed to make this possible in XSLT 2.0?

Thanks,

-- 

joe

Current Thread