Extension functions written in XSLT are defined by the exsl:function
element, which can occur only at the top level of the stylesheet.
Issue: Wrapper - should there be a wrapper element to contain the exsl:function
elements in a document?
Issue: Conditions - should xsl:if
and xsl:choose
be allowed as direct children of exsl:function
? It makes it easier to do conditional processing if they are. But conditional processing could alternatively be achieved through an extension to XPath syntax that gave a conditional construct.
An exsl:function
element must have a name
attribute, indicating the name of the function. The value of the name
attribute is a QName, which is expanded as described in Section 2.4 [Qualified Names] in the XSLT 1.0 Recommendation. It is an error if the namespace URI of the expanded name of the function is null - extension functions must not be in a null namespace.
Note: the rules on resolving qualified names entail that if no prefix is defined, the namespace URI resolves to the null namespace. Thus, it is an error if the qualified name specified does not have a prefix.
When an extension function defined with exsl:function
is called, the content of the exsl:function
is instantiated to give the return value of the function.
It is an error if the instantiation of the content of exsl:function
results in the creation of result tree nodes unless they are created as part of a result tree fragment. An XSLT processor may signal the error; if it does not signal the error, it must recover by ignoring the result tree nodes.
Issue: RTF error - should generating result nodes be an unrecoverable error?
The implication of this is that literal result elements, xsl:copy
, xsl:copy-of
, xsl:element
, xsl:attribute
, xsl:processing-instruction
, xsl:comment
, xsl:text
, xsl:value-of
and xsl:number
elements must not be instantiated during the instantiation of the content of exsl:function
, unless they are instantiated during the creation of a result tree fragment (i.e. within xsl:variable
, xsl:param
, xsl:with-param
or exsl:return
).
It is an error if the instantiation of the content of exsl:function
results in a call to or application of a template unless the template is called or applied within a variable-binding element such as xsl:variable
or xsl:param
or within exsl:return
.
Issue: Templates - should it be possible to call or apply templates within exsl:function
outside variable-binding elements? Given that generating result nodes is an error, the only purpose of calling or applying templates would be for templates that generate messages. This is achievable using an extension function instead.
It is an error if the instantiation of the content of exsl:function
results in an xsl:for-each
element being instantiated unless the xsl:for-each
is within a variable-binding element such as xsl:variable
or xsl:param
or within exsl:return
.
Issue: xsl:for-each
- should xsl:for-each
be allowed within exsl:function
outside variable-binding elements? It would ease the return of node sets created (a) from other documents or (b) involving sorting the node set in other than document order. This is achievable by building an RTF with IDs referring to the relevant nodes instead.
Defining Function Arguments
Arguments for functions are defined with the xsl:param
element, as specified in Section 11 [Variables and Parameters] of the XSLT 1.0 Recommendation.
Issue: Arguments - should arguments be specified with the xsl:param
element or through attributes on exsl:function
? One problem with specifying them as arguments is that the attribute order is not guaranteed; this wouldn't be a problem if arguments were passed by name rather than position.
When an extension function is called with arguments passed by position, the values passed as arguments are assigned to parameters according to the position of the xsl:param
. The first argument is assigned to the first parameter, the second to the second and so on. The presence of an xsl:param
indicates that an argument is expected for the function but does not imply that an argument has to be passed to the function.
Issue: Optional arguments - should there be an extension attribute on xsl:param
that indicates whether an argument is optional?
An XSLT processor must not signal an error if an extension function is called with fewer arguments than there are parameters defined for the extension function. It is an error to call a function with more arguments than there are parameters defined for the extension function. An XSLT processor may signal the error; if it does not signal the error, then it must recover by ignoring the extra arguments.
Issue: Argument error - should trying to pass more arguments than there are xsl:param
elements be considered an error? Should it be an unrecoverable error?
As an example, take the following function definition:
<exsl:function name="my:func">
<xsl:param name="foo" />
<xsl:param name="bar" select="false()" />
...
</exsl:function>
All the following function calls are legal:
my:func()
my:func('Fred')
my:func('Fred', true())
my:func('Fred', 'Barney')
The following function call is illegal:
my:func('Fred', true(), 'Barney')
The value specified by an xsl:param
indicates the default value for an argument if that argument is not given in a function call, but does not indicate the acceptable value types for the function.
Issue: Argument types - should there be an extension attribute on xsl:param
that indicates the value type of an argument?
Defining Function Return Values
When a function is called, the content of the exsl:function
element is instantiated to give the return value of the function. The instantiation of the content of the exsl:function
element may involve the instantiation of an exsl:return
element.
An implementation of this extension
element
in the EXSLT func namespace must conform to the behaviour described in this document.
This material is in the public domain.