<?xml version="1.0" encoding="iso-8859-1"?> <?xml-stylesheet href="../make-menu.xsl" type="text/xsl"?><html> <head> <this-is section="xsl-elements" page="function" subpage=""/> <!-- Generated at 2011-12-09T20:47:22.916Z--><title>Saxonica: XSLT and XQuery Processing: xsl:function</title> <meta name="coverage" content="Worldwide"/> <meta name="copyright" content="Copyright Saxonica Ltd"/> <meta name="title" content="Saxonica: XSLT and XQuery Processing: xsl:function"/> <meta name="robots" content="noindex,nofollow"/> <link rel="stylesheet" href="../saxondocs.css" type="text/css"/> </head> <body class="main"> <h1>xsl:function</h1> <p>The <code>xsl:function</code> 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.</p> <p>Example:</p> <div class="codeblock" style="border: solid thin; background-color: #B1CCC7; padding: 2px"> <pre> <code><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)"/></code> </pre> </div> <p>In limited circumstances, stylesheet functions (<code>xsl:function</code>) optimise tail-recursion. The circumstances are that the <code>select</code> expression of the <code>xsl:result</code> instruction must contain a call on the same function as the <code>then</code> or <code>else</code> 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):</p> <div class="codeblock" style="border: solid thin; background-color: #B1CCC7; padding: 2px"> <pre> <code><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></code> </pre> </div> <p>The call <code>x:factorial(1, 5)</code> returns 120.</p> <p>Saxon defines an extra attribute on <code>xsl:function</code>: <code>saxon:memo-function="yes"</code> 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 <a class="bodylink" href="../extensions/attributes/memo-function.xml">saxon:memo-function</a>.</p> <table width="100%"> <tr> <td> <p align="right"><a class="nav" href="if.xml">Next</a></p> </td> </tr> </table> </body> </html>