Re: [xsl] xsl:key and document()

Subject: Re: [xsl] xsl:key and document()
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 9 Jan 2001 09:07:44 +0000
Hi Robert,

You wrote about indexing into a separate document using a key and not
wanting to use a variable as the second argument to key().

David Carlisle wrote:
> You could use document() with the URI of your original source
> document but that would (I think) give you a new node set, not the
> original one. Two calls to document() with the same URI are
> guaranteed to return the same node set (even if that URI actually
> returns different entities at different times) but that doesn't
> apply to the original source document and an `equivalent' document()
> call.

Another problem with using document() with the URI of the original
source document is, of course, that the original source document might
change depending on the run of the stylesheet, so you can't hard-code
it into the stylesheet.  That means you have to either pass it as a
parameter into the stylesheet or define the URL of the document within
the document itself.

Also remember that the URL of the document will be resolved relative
to the URL of the stylesheet containing the call to document, unless a
second argument is given. Whether defined as a parameter or within the
document itself, the URL would have to be defined relative to the
stylesheet, or a second argument passed to the call to document()
giving a node in the original document, which involves using a...
variable.

This would be slightly easier if there was a special case to get the
source document, such as a call to document without any arguments, or
one where the first string is '#source' (dangerous 'cos that looks
like a URL fragment identifier), or possibly a means of getting the
URL of the source document through something like system-property():

  system-property('xsl:source-uri')

In an even worse case, you might not be able to retrieve the document
at all like this: there's nothing to say that the source XML for a
transformation has to come from a document in the first place...

If I'm using multiple documents, I usually have a global variable
holding the root node of the source so that I can always get back to
it easily wherever I am:

<xsl:variable name="source" select="/" />

If you did this, you could do:

   <xsl:for-each select="document('LUType.xml')">
      <xsl:value-of select="key('LUType', $source/Tag/@ID)" />
   </xsl:for-each>

for example.

If you are just interested in the value of the (first) node that's
returned when accessing the key (rather than wanting to index into it
in any other way) then you could write a named template that would
collect the value for you.  The template would look like:

<xsl:template name="key">
   <xsl:param name="key-value" />
   <xsl:for-each select="document('LUType.xml')">
      <xsl:value-of select="key('LUType', $key-value)" />
   </xsl:for-each>
</xsl:template>

You could then call it like:

  <xsl:call-template name="key">
    <xsl:with-param name="key-value" select="Tag/@ID" />
  </xsl:call-template>

This would ensure that you didn't change the current node in your main
template, but the template can only return a result tree fragment and
you possibly need it to return something more useful.

But variables are your friends - there's no reason to avoid them :)

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