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
XPath API for Java
Saxon on .NET
Extensibility
Saxon Extensions
| Introduction
| EXSLT Extensions
| Extension attributes (XSLT only)
| Additional serialization parameters
» | Extension functions
| Extension instructions
Sample Saxon Applications
The Saxon SQL Extension
XSLT Elements
XPath 2.0 Expression Syntax
Function Library
Standards Conformance

# saxon:function()

saxon:function($arg1 as xs:string, $arg2 as xs:integer) ==> jt:net.sf.saxon.expr.UserFunctionCall

This function is available only in Saxon-SA

This function takes as its arguments the name and arity of a user-defined function (a function declared using "declare function" in XQuery, or <xsl:function> in XSLT), and returns a value that represents the function and can be used to invoke the function using saxon:call. This allows higher-order functions to be implemented in XSLT and XQuery, that is, functions that take other functions as arguments. An example of such a higher-order function is saxon:for-each-group, which provides grouping capability in XQuery similar to that of the `xsl:for-each-group` instruction in XSLT.

The arguments must be specified as literals (this function is always evaluated at compile time).

Here is an example, the textbook `fold` function in XSLT:

    <xsl:function name="f:fold">
      <xsl:param name="sequence"/>
      <xsl:param name="operation"/>
      <xsl:param name="start-value"/>
      <xsl:sequence select="if (empty($sequence))
                            then $start-value
                            else f:fold(remove($sequence, 1),
                                        $operation,
                                        saxon:call($operation,
                                                   $start-value,
                                                   $sequence[1])"/>
    </xsl:function>

    <xsl:function name="f:plus">
      <xsl:param name="a"/>
      <xsl:param name="b"/>
      <xsl:sequence select="$a + $b"/>
    </xsl:function>

    <xsl:function name="f:times">
      <xsl:param name="a"/>
      <xsl:param name="b"/>
      <xsl:sequence select="$a * $b"/>
    </xsl:function>

    <xsl:function name="f:sum">
      <xsl:param name="sequence"/>
      <xsl:sequence select="f:fold($sequence, saxon:function('f:plus', 2), 0)"/>
    </xsl:function>

    <xsl:function name="f:product">
      <xsl:param name="sequence"/>
      <xsl:sequence select="f:fold($sequence, saxon:function('f:times', 2), 0)"/>
    </xsl:function>

Here is the same example in XQuery:

    declare function f:fold (
             $sequence as xs:double*, $operation, $start-value as xs:double) {
         if (empty($sequence))
         then $start-value
         else f:fold(remove($sequence, 1),
                     $operation,
                     saxon:call($operation, $start-value, $sequence[1]))
    };

    declare function f:plus ($a as xs:double, $b as xs:double) {$a + $b};

    declare function f:times ($a as xs:double, $b as xs:double) {$a * $b};

    declare function f:sum ($sequence as xs:double*) as xs:double {
       f:fold($sequence, saxon:function('f:plus', 2), 0)
    };

    declare function f:product ($sequence as xs:double*) as xs:double {
       f:fold($sequence, saxon:function('f:times', 2), 1)
    };

The result of `f:sum(1 to 4)` is 10, while the result of `f:product(1 to 4)` is 24.

Higher-order functions allow many generic functions such as `fold` to be written, and their availability in Saxon-SA turns XSLT and XQuery into fully-fledged functional programming languages.

The type of the result of saxon:function is `jt:net.sf.saxon.expr.UserFunctionCall`, where the prefix `jt` represents the URI `http://net.sf.saxon/java-type`.

Next