SAXONICA

Saxon Documentation
Full Contents
About Saxon
Changes in this Release
Conditions of Use
Using XSLT 2.0
Using XQuery
Handling Source Documents
XML Schema Processing
The XPath API
Standards Conformance
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
XPath 2.0 Expression Syntax
Function Library
XSLT Patterns

# 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">
    <xsl:param name="number" as="xs:integer"/>
    <xsl:sequence as="xs:integer"
                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