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:package
               ; xsl:stylesheet
               ; xsl:transform
               ; xsl:override
            
Attributes
| 
                   | 
                   | Name of the function. Must be in a non-default namespace. | 
| 
                   | 
                   | Defines the return type of the function. | 
| 
                   | 
                   | New in XSLT 3.0. Determines the visibility of the function in other packages. | 
| 
                   | 
                   | Not implemented in Saxon 9.7. | 
| 
                   | 
                   | Determines what happens
                    if this function has the same name and arity as another provided by the
                    implementation or made available in the static context by an
                    implementation-defined mechanism. If the value is  | 
| 
                   | 
                   | A deprecated synonym of
                         | 
| 
                   | 
                   | Assigns the function to one of three
                    categories regarding the determinism of functions (relevant to optimization).
                    The value  | 
| 
                   | 
                   | Indicates whether the function is to cache its results. 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 new-each-time are interpreted
                    in Saxon 9.7 (PE or higher) as follows: if the value of cache is
                        full or partial, and the value of
                        new-each-time 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.7 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 since Saxon 9.6 as part of
                    the implementation of XSLT 3.0 packages.
Saxon, as at version 9.7, does not yet implement the new XSLT 3.0 attribute
                        streamability: 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 which constitutes the enclosed sequence constructor 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.