xsl:function

Defines a function within a stylesheet. The function is written in XSLT but it may be called from any XPath expression in the stylesheet. It must have a non-default namespace prefix.

Category: declaration
Content: ( xsl:param* , sequence-constructor )
Permitted parent elements: xsl:stylesheet ; xsl:transform ; xsl:override

Attributes

name

eqname

as?

sequence-type

visibility?

"public" | "private" | "final" | "abstract"

Implemented in Saxon 9.6 as part of the limited and experimental implementation of XSLT 3.0 packages.

streamable?

boolean

Not implemented in Saxon 9.6.

override-extension-function?

boolean

[override]?

boolean

identity-sensitive?

boolean

Requires Saxon-PE or Saxon-EE.

cache?

"full" | "partial" | "no"

Requires Saxon-PE or Saxon-EE.

Notes on the Saxon implementation

Saxon defines an extra attribute on xsl:function, namely saxon:memo-function. The attribute saxon:memo-function="yes" indicates that Saxon should remember the results of calling the function in a cache, and if the function is called again with the same arguments, the result is retrieved from the cache rather than being recalculated.

The extension attribute saxon:explain can also be used on an xsl:function element. If the attribute has value yes, then at compile time Saxon outputs (to the standard error output) a representation of the optimized expression tree for that function.

The attributes cache and identity-sensitive are interpreted in Saxon 9.6 (PE or higher) as follows: if the value of cache is full or partial, and the value of identity-sensitive is no then the function is implemented as a memo function, in the same way as when the extension attribute saxon:memo-function is set. Note that the cache used for a memo function in Saxon 9.6 is always a full cache, that is, it retains the results of all previous function calls within the scope of a query or transformation. In Saxon-HE, these attributes have no effect.

The visibility attribute is implemented in Saxon 9.6 as part of the limited and experimental implementation of XSLT 3.0 packages.

Saxon, as at version 9.6, does not yet implement the new XSLT 3.0 attribute streamable: calls to stylesheet functions are not streamable, except in cases where the optimizer is able to inline the function.

Details

In limited circumstances, stylesheet functions (xsl:function) optimise tail-recursion. The circumstances are that the select expression of the xsl:sequence instruction must contain a call on the same function as the then or else part of a conditional expression (which may be nested in further conditional expressions). It may require a little care to write functions to exploit this. See the examples below.

Examples

Example 1

The following example is not tail-recursive, because the recursive call is within an arithmetic expression: the multiplication takes place on return from the recursive call.

<xsl:function name="my:factorial" as="xs:integer"> <xsl:param name="number" as="xs:integer"/> <xsl:sequence select="if ($number=0) then 1 else $number * my:factorial($number-1)"/> </xsl:function>

Example 2

The previous example can be recast in tail-recursive form by adding an extra parameter (which should be set to 1 on the initial call):

<xsl:function name="x:factorial"> <xsl:param name="acc" as="xs:integer?"/> <xsl:param name="n" as="xs:integer"/> <xsl:sequence as="xs:integer" select="if ($n = 1) then $acc else x:factorial($acc*$n, $n - 1)" /> </xsl:function>

The call x:factorial(1, 5) returns 120.

Links to W3C specifications

XSLT 2.0 Specification

XSLT 3.0 Specification

See also

saxon:memo-function