RE: [xsl] Functions Returning Nodes in XSLT 2.0

Subject: RE: [xsl] Functions Returning Nodes in XSLT 2.0
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 20 May 2005 14:17:31 +0100
>     In XSLT 2.0 with Saxon 8.4...
> 
>     I've written helper methods that look like so.
> 
>     <xsl:function name="fn:user" as="element()">
>       <xsl:param name="login"/>
>       <xsl:copy-of
>         select="document('users.xml')/users/user[login = $login]"/>
>     </xsl:function>
> 
>     Making it easier to write select attributes.
> 
>     <xsl:value-of select="fn:user()/first-name"/>
> 
>     Some of my XPath is getting complicated, so I like to wrap it up
>     into functions.
> 
>     I'm wondering if copy-of is smart enough to forgo copying in
>     such cases. If not, I could see how it could get expensive to
>     call fn:user every time I wanted a property.
> 
>     Is there a better practice for this sort of thing? 

You'd be better off using xsl:sequence rather than xsl:copy if you don't
want a copy. The semantics are different: with xsl:sequence you will get the
same node back if you call the function twice with the same arguments, with
xsl:copy-of you will get a different node back.

In fact I'm exploiting this difference to do a new optimization in the next
Saxon release: a construct of the form above (using copy-of) will be able to
read the user element from the source XML document without actually building
a tree for the entire source document in memory. Although the semantics of
document() require that two calls with the same URI return the same node, a
call to document() within xsl:copy-of can be regarded as a function that
returns the document with the opposite guarantee, that you will get
different nodes each time: which means that the source document will be read
repeatedly rather than being stored in memory. In your case this is not the
right strategy!

Another new optimization that's coming along soon is that an expression like
the one in your example will automatically use indexing without you asking
for it. In the meantime, though, using xsl:key for this kind of construct is
usually a good idea.

Michael Kay
http://www.saxonica.com/

Current Thread