What Constraints Apply to xsl:function in XSLT?
In XSLT development, stylesheets frequently require reusable logic to
transform or compute data, which can be implemented using either named
templates (<xsl:template name="...">) or stylesheet
functions (<xsl:function>). While named templates
focus on generating output nodes within the execution flow, stylesheet
functions—introduced in XSLT 2.0—are designed to compute and return
typed values directly inside XPath expressions. This architectural
difference imposes specific constraints on
<xsl:function> implementations regarding context
access, namespace scoping, parameter behavior, and tree
modification.
Undefined Initial Context
The most prominent constraint in <xsl:function> is
the absence of an implicit context item. When a function is
evaluated:
- The context item (
.), context position (position()), and context size (last()) are undefined upon entry. - Relative XPath expressions (such as
item/priceor@id) cannot be resolved directly inside the function body unless a node is explicitly passed as an argument. - Named templates inherit the current context item, position, and size from the calling instruction, allowing direct execution of contextual path queries.
Mandatory Namespace Prefix
XSLT requires strict namespace separation to prevent collisions with built-in XPath and XSLT functions:
- The
nameattribute of<xsl:function>must be an expanded QName with a non-null namespace prefix (for example,my:calculate-total()). - Defining a function in the default (unprefixed) namespace or the
standard XSLT namespace
(
[http://www.w3.org/1999/XSL/Transform](http://www.w3.org/1999/XSL/Transform)) results in a static compile-time error. - Standard named templates can use simple, unprefixed NCName
identifiers (such as
name="formatDate").
Strict Parameter Rules and Arity
Parameter handling inside functions is strictly typed and governed by function signatures:
- No Default Values: In standard XSLT 2.0 and 3.0,
<xsl:param>elements inside<xsl:function>cannot specify default values viaselector content. Every declared parameter must be supplied by the caller. - Exact Arity Matching: Functions are identified by
their qualified name and arity (number of arguments). A function
my:format(arg1)is distinct frommy:format(arg1, arg2). - No Tunnel Parameters: Functions do not support
tunnel parameters (
tunnel="yes"), which are widely used in named and rule-based templates to pass values across deep transformation hierarchies.
Determinism and Side-Effect Restrictions
Stylesheet functions are intended to be pure, side-effect-free operations:
- Functions cannot execute instructions that write to secondary output
streams, such as
<xsl:result-document>. - Functions return an explicit sequence or typed value constructed by
<xsl:sequence>or literal result elements, rather than appending directly to the primary result tree of a calling template. - In streaming environments (XSLT 3.0), functions face additional static restrictions regarding consuming streamable nodes compared to template rules.
Invocation and Matching
The execution model differs fundamentally between the two constructs:
- Functions can only be invoked within XPath expressions (e.g.,
<xsl:value-of select="my:add(1, 2)"/>). - Functions cannot specify
matchpatterns, executionmodeattributes, or rule priorities, making them unsuitable for polymorphic node dispatching where<xsl:apply-templates>is required.