Re: Designs for XSLT functions (Was: Re: [xsl] RE: syntax sugar for call-template)

Subject: Re: Designs for XSLT functions (Was: Re: [xsl] RE: syntax sugar for call-template)
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Tue, 20 Feb 2001 18:12:19 +0000
Hi Uche,

>> Firstly, as we know, key() and id() are restricted to finding nodes in
>> the current tree. If I want to use an extension function that
>> retrieves keyed nodes in a particular document then I need to be able
>> to do:
>> 
>> <exsl:function name="my:key">
>>    <xsl:param name="key-name" />
>>    <xsl:param name="key-value" />
>>    <xsl:param name="file-name" />
>>    <xsl:param name="base-node" select="/" />
>>    <xsl:for-each select="document($file-name, $base-node)">
>>       <exsl:result select="key($key-name, $key-value)" />
>>    </xsl:for-each>
>> </exsl:function>
>
> I see the general gist here. However, note that since XPath 1.0
> doesn't have a general list type (which I think is near imperative
> for the next XPath) it could be quite a pain to validate the idea
> that "multiple exsl:result" elements are allowed as long as each
> evaluates to a node set".

Oh, sorry - that wasn't the intention of my example.  In the example
above, I was assuming that $file-name was a string, and that therefore
the xsl:for-each only selected one node - it's essentially being used
to change the current node so that the call to key() uses that
document as its scope.

So the exsl:result would only actually occur once, and that would be
the node set returned.

If I wanted to make this work with multiple documents, I'd use a
recursive solution:

<exsl:function name="my:key">
   <xsl:param name="key-name" />
   <xsl:param name="key-value" />
   <xsl:param name="file-names" />
   <xsl:param name="base-node" select="/" />
   <xsl:variable name="rest"
                 select="my:key($key-name, $key-value,
                                $file-names[position() > 1],
                                $base-node)" />
   <xsl:for-each select="document($file-name[1], $base-node)">
      <exsl:result select="key($key-name, $key-value) | $rest" />
   </xsl:for-each>
</exsl:function>

In other words: only one exsl:result element should be instantiated
when the content of exsl:function is processed - if more than one is
instantiated then only the first actually matters, the rest are
ignored.

Would that be implementable?

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/



 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread