SAXONICA

Saxon Documentation
Full Contents
About Saxon
Changes in this Release
Notices
Using XSLT 2.0
Using XQuery
Handling Source Documents
XML Schema Processing
XPath API for Java
Saxon on .NET
Extensibility
Saxon Extensions
Sample Saxon Applications
The Saxon SQL Extension
XSLT Elements
| Introduction
| xsl:analyze-string
| xsl:apply-imports
| xsl:apply-templates
| xsl:attribute
| xsl:attribute-set
| xsl:call-template
| xsl:character-map
| xsl:choose
| xsl:comment
| xsl:copy
| xsl:copy-of
| xsl:decimal-format
| xsl:document
| xsl:element
| xsl:fallback
| xsl:for-each
| xsl:for-each-group
» | xsl:function
| xsl:if
| xsl:include
| xsl:import
| xsl:import-schema
| xsl:key
| xsl:matching-substring
| xsl:message
| xsl:namespace
| xsl:namespace-alias
| xsl:next-match
| xsl:non-matching-substring
| xsl:number
| xsl:otherwise
| xsl:output
| xsl:output-character
| xsl:param
| xsl:perform-sort
| xsl:preserve-space
| xsl:processing-instruction
| xsl:result-document
| xsl:sequence
| xsl:sort
| xsl:strip-space
| xsl:stylesheet
| xsl:template
| xsl:text
| xsl:value-of
| xsl:variable
| xsl:when
| xsl:with-param
| Literal Result Elements
| XSLT Patterns
XPath 2.0 Expression Syntax
Function Library
Standards Conformance

# xsl:function

The `xsl:function` element 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.

Example:

    <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)"/>

In limited circumstances, stylesheet functions (`xsl:function`) now optimise tail-recursion. The circumstances are that the `select` expression of the `xsl:result` 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. The example above is not tail-recursive, because the recursive call is within an arithmetic expression: the multiplication takes place on return from the recursive call. It 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.

Saxon defines an extra attribute on `xsl:function`: `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. Further details: see saxon:memo-function.

Next