24 Extensibility and Fallback

XSLT allows two kinds of extension, extension instructions and extension functions.

[Definition: An extension instruction is an element within a sequence constructor that is in a namespace (not the XSLT namespace) designated as an extension namespace.]

[Definition: An extension function is a named function introduced to the static or dynamic context by mechanisms outside the scope of this specification.]

This specification does not define any mechanism for creating or binding implementations of extension instructions or extension functions, and it is not required that implementations support any such mechanism. Such mechanisms, if they exist, are implementation-defined. Therefore, an XSLT stylesheet that must be portable between XSLT implementations cannot rely on particular extensions being available. XSLT provides mechanisms that allow an XSLT stylesheet to determine whether the implementation makes particular extensions available, and to specify what happens if those extensions are not available. If an XSLT stylesheet is careful to make use of these mechanisms, it is possible for it to take advantage of extensions and still retain portability.

[ERR XTSE0085] It is a static error to use a reserved namespace in the name of any extension function or extension instruction, other than a function or instruction defined in this specification or in a normatively referenced specification. It is a static error to use a prefix bound to a reserved namespace in the [xsl:]extension-element-prefixes attribute.

24.1 Extension Functions

The set of functions that can be called from a FunctionCallXP30 within an XPath expression may include one or more extension functions. The expanded QName of an extension function always has a non-null namespace URI, which must not be the URI of a reserved namespace.

Note:

The definition of the term extension function is written to exclude user-written stylesheet functions, constructor functions for built-in and user-defined types, functions in the fn, math, map, and array namespaces, anonymous XPath inline functions, maps and arrays (see 27.7.1 Arrays), and partial function applications (including partial applications of extension functions). It also excludes functions obtained by invoking XPath-defined functions such as load-xquery-moduleFO31. The definition allows extension functions to be discovered at evaluation time (typically using function-lookupFO30) rather than necessarily being known statically.

Technically, the definition of extension functions excludes anonymous functions obtained by calling or partially applying other extension functions. Since such functions are by their nature implementation-defined, they may however share some of the characteristics of extension functions.

24.1.1 fn:function-available

Summary

Determines whether a particular function is or is not available for use. The function is particularly useful for calling within an [xsl:]use-when attribute (see 3.13.1 Conditional Element Inclusion) to test whether a particular extension function is available.

Signatures
fn:function-available($function-name as xs:string) as xs:boolean
fn:function-available( $function-name  as xs:string,
$arity  as xs:integer) as xs:boolean
Properties

This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on namespaces, and known function signatures.

Rules

A function is said to be available within an XPath expression if it is present in the statically known function signaturesXP30 for that expression (see 5.3.1 Initializing the Static Context). Functions in the static context are uniquely identified by the name of the function (a QName) in combination with its arity.

The value of the $function-name argument must be a string containing an EQName. The lexical QName is expanded into an expanded QName using the namespace declarations in scope for the expression. If the value is an unprefixed lexical QName, then the standard function namespace is used in the expanded QName.

The two-argument version of the function-available function returns true if and only if there is an available function whose name matches the value of the $function-name argument and whose arity matches the value of the $arity argument.

The single-argument version of the function-available function returns true if and only if there is at least one available function (with some arity) whose name matches the value of the $function-name argument.

When the containing expression is evaluated with XPath 1.0 compatibility mode set to true, the function-available function returns false in respect of a function name and arity for which no implementation is available (other than the fallback error function that raises a dynamic error whenever it is called). This means that it is possible (as in XSLT 1.0) to use logic such as the following to test whether a function is available before calling it:

Example: Calling an extension function with backwards compatibility enabled
<summary xsl:version="1.0">
  <xsl:choose>
    <xsl:when test="function-available('my:summary')">
      <xsl:value-of select="my:summary()"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:text>Summary not available</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</summary>
Error Conditions

[ERR XTDE1400] It is a dynamic error if the argument does not evaluate to a string that is a valid EQName, or if the value is a lexical QName with a prefix for which no namespace declaration is present in the static context. If the processor is able to detect the error statically (for example, when the argument is supplied as a string literal), then the processor may optionally signal this as a static error.

Notes

The fact that a function with a given name is available gives no guarantee that any particular call on the function will be successful. For example, it is not possible to determine the types of the arguments expected.

The introduction of the function-lookupFO30 function in XPath 3.0 reduces the need for function-available, since function-lookupFO30 not only tests whether a function is available, but also returns a function item that enables it to be dynamically called.

If a function is present in the static context but with no useful functionality (for example, if the system has been configured for security reasons so that available-environment-variablesFO30 returns no information), then function-available when applied to that function should return false.

It is not necessary that there be a direct equivalence between the results of function-available and function-lookupFO30 in all cases. For example, there may be extension functions whose side-effects are such that for security reasons, dynamic calls to the function are disallowed; function-lookupFO30 might then not provide access to the function. The main use-case for function-available, by contrast, is for use in [xsl:]use-when conditions to test whether static calls on the function are possible.

Examples
Example: Stylesheet portable between XSLT 1.0, XSLT 2.0, and XSLT 3.0

A stylesheet that is designed to use XSLT 2.0 facilities when running under an XSLT 2.0 or XSLT 3.0 processor, but to fall back to XSLT 1.0 capabilities when not, might be written using the code:

<out xsl:version="2.0">
  <xsl:choose>
    <xsl:when test="function-available('matches')">
      <xsl:value-of select="matches(/doc/title, '[a-z]*')"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="string-length(
	        translate(/doc/title, 'abcdefghijklmnopqrstuvwxyz', '')) = 0"/>
    </xsl:otherwise>
  </xsl:choose>
</out>

Here an XSLT 2.0 or XSLT 3.0 processor will always take the xsl:when branch, while a 1.0 processor will follow the xsl:otherwise branch. The single-argument version of the function-available function is used here, because that is the only version available in XSLT 1.0. Under the rules of XSLT 1.0, the call on the matches function is not an error, because it is never evaluated.

 

Example: Stylesheet portable between XSLT 3.0 and a future version of XSLT

A stylesheet that is designed to use facilities in some future XSLT version when they are available, but to fall back to XSLT 2.0 or XSLT 3.0 capabilities when not, might be written using code such as the following. This hypothesizes the availability in some future version of a function pad which pads a string to a fixed length with spaces:

<xsl:value-of select="pad(/doc/title, 10)" 
               use-when="function-available('pad', 2)"/>
 <xsl:value-of select="concat(/doc/title, string-join(
                          for $i in 1 to 10 - string-length(/doc/title) 
						  return ' ', ''))"
               use-when="not(function-available('pad', 2))"/>
 

In this case the two-argument version of function-available is used, because there is no requirement for this code to run under XSLT 1.0.

24.1.2 Calling Extension Functions

If the function name used in a FunctionCallXP30 within an XPath expression identifies an extension function, then to evaluate the FunctionCallXP30, the processor will first evaluate each of the arguments in the FunctionCallXP30. If the processor has information about the datatypes expected by the extension function, then it may perform any necessary type conversions between the XPath datatypes and those defined by the implementation language. If multiple extension functions are available with the same name, the processor may decide which one to invoke based on the number of arguments, the types of the arguments, or any other criteria. The result returned by the implementation is returned as the result of the function call, again after any necessary conversions between the datatypes of the implementation language and those of XPath. The details of such type conversions are outside the scope of this specification.

[ERR XTDE1420] It is a dynamic error if the arguments supplied to a call on an extension function do not satisfy the rules defined for that particular extension function, or if the extension function reports an error, or if the result of the extension function cannot be converted to an XPath value.

Note:

Implementations may also provide mechanisms allowing extension functions to report recoverable dynamic errors, or to execute within an environment that treats some or all of the errors listed above as recoverable.

[ERR XTDE1425] When the containing element is processed with XSLT 1.0 behavior, it is a dynamic error to evaluate an extension function call if no implementation of the extension function is available.

Note:

When XSLT 1.0 behavior is not enabled, this is a static error [ERR XPST0017] XP30.

Note:

There is no prohibition on calling extension functions that have side-effects (for example, an extension function that writes data to a file). However, the order of execution of XSLT instructions is not defined in this specification, so the effects of such functions are unpredictable.

Implementations are not required to perform full validation of values returned by extension functions. It is an error for an extension function to return a string containing characters that are not permitted in XML, but the consequences of this error are implementation-defined. The implementation may raise an error, may convert the string to a string containing valid characters only, or may treat the invalid characters as if they were permitted characters.

Note:

The ability to execute extension functions represents a potential security weakness, since untrusted stylesheets may invoke code that has privileged access to resources on the machine where the processor executes. Implementations may therefore provide mechanisms that restrict the use of extension functions by untrusted stylesheets.

All observations in this section regarding the errors that can occur when invoking extension functions apply equally when invoking extension instructions.

24.1.3 External Objects

An implementation may allow an extension function to return an object that does not have any natural representation in the XDM data model, whether as an atomic value, a node, or a function item. For example, an extension function sql:connect might return an object that represents a connection to a relational database; the resulting connection object might be passed as an argument to calls on other extension functions such as sql:insert and sql:select.

The way in which such objects are represented in the type system is implementation-defined. They might be represented by a completely new datatype, or they might be mapped to existing datatypes such as integer, string, or anyURI.

24.1.4 fn:type-available

Summary

Used to control how a stylesheet behaves if a particular schema type is or is not available in the static context.

Signature
fn:type-available($type-name as xs:string) as xs:boolean
Properties

This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on namespaces, and schema definitions.

Rules

A schema type (that is, a simple type or a complex type) is said to be available within an XPath expression if it is a type definition that is present in the in-scope schema typesXP30 for that expression (see 5.3.1 Initializing the Static Context). This includes built-in types, types imported using xsl:import-schema, and extension types defined by the implementation.

The value of the $type-name argument must be a string containing an EQName. The EQName is expanded into an expanded QName using the namespace declarations in scope for the expression. If the value is an unprefixed lexical QName, then the default namespace is used in the expanded QName.

The function returns true if and only if there is an available type whose name matches the value of the $type-name argument.

Error Conditions

[ERR XTDE1428] It is a dynamic error if the argument does not evaluate to a string that is a valid EQName, or if the value is a lexical QName with a prefix for which no namespace declaration is present in the static context. If the processor is able to detect the error statically (for example, when the argument is supplied as a string literal), then the processor may optionally signal this as a static error.

Notes

The type-available function is of limited use within an [xsl:]use-when expression, because the static context for the expression does not include any user-defined types.

24.2 Extension Instructions

[Definition: The extension instruction mechanism allows namespaces to be designated as extension namespaces. When a namespace is designated as an extension namespace and an element with a name from that namespace occurs in a sequence constructor, then the element is treated as an instruction rather than as a literal result element.] The namespace determines the semantics of the instruction.

Note:

Since an element that is a child of an xsl:stylesheet element is not occurring in a sequence constructor , user-defined data elements (see 3.7.3 User-defined Data Elements) are not extension elements as defined here, and nothing in this section applies to them.

24.2.1 Designating an Extension Namespace

A namespace is designated as an extension namespace by using an [xsl:]extension-element-prefixes attribute on an element in the stylesheet (see 3.4 Standard Attributes). The attribute must be in the XSLT namespace only if its parent element is not in the XSLT namespace. The value of the attribute is a whitespace-separated list of namespace prefixes. The namespace bound to each of the prefixes is designated as an extension namespace.

The default namespace (as declared by xmlns) may be designated as an extension namespace by including #default in the list of namespace prefixes.

A reserved namespace cannot be designated as an extension namespace: see [see ERR XTSE0085].

[ERR XTSE1430] It is a static error if there is no namespace bound to the prefix on the element bearing the [xsl:]extension-element-prefixes attribute or, when #default is specified, if there is no default namespace.

The designation of a namespace as an extension namespace is effective for the element bearing the [xsl:]extension-element-prefixes attribute and for all descendants of that element within the same stylesheet module.

24.2.2 fn:element-available

Summary

Determines whether a particular instruction is or is not available for use. The function is particularly useful for calling within an [xsl:]use-when attribute (see 3.13.1 Conditional Element Inclusion) to test whether a particular extension instruction is available.

Signature
fn:element-available($element-name as xs:string) as xs:boolean
Properties

This function is deterministicFO30, context-dependentFO30, and focus-independentFO30. It depends on namespaces.

Rules

The value of the $element-name argument must be a string containing an EQName. If it is a lexical QName with a prefix, then it is expanded into an expanded QName using the namespace declarations in the static context of the expression. If there is a default namespace in scope, then it is used to expand an unprefixed lexical QName.

If the resulting expanded QName is in the XSLT namespace, the function returns true if and only if the local name matches the name of an XSLT element that is defined in this specification and implemented by the XSLT processor.

If the expanded QName has a null namespace URI, the element-available function will return false.

If the expanded QName is not in the XSLT namespace, the function returns true if and only if the processor has an implementation available of an extension instruction with the given expanded QName. This applies whether or not the namespace has been designated as an extension namespace.

If the processor does not have an implementation of a particular extension instruction available, and such an extension instruction is evaluated, then the processor must perform fallback for the element as specified in 24.2.3 Fallback. An implementation must not signal an error merely because the stylesheet contains an extension instruction for which no implementation is available.

Error Conditions

[ERR XTDE1440] It is a dynamic error if the argument does not evaluate to a string that is a valid EQName, or if the value is a lexical QName with a prefix for which no namespace declaration is present in the static context. If the processor is able to detect the error statically (for example, when the argument is supplied as a string literal), then the processor may optionally signal this as a static error.

Notes

For element names in the XSLT namespace:

  • This function can be useful to distinguish processors that implement XSLT 3.0 from processors that implement other (older or newer) versions of the specification, and to distinguish full implementations from incomplete implementations. (Incomplete implementations, of course, cannot be assumed to behave as described in this specification.)

  • In earlier versions of this specification, element-available was defined to return true only for elements classified as instructions. The distinction between instructions and other elements, however, is sometimes rather technical, and in XSLT 3.0 the effect of the function has therefore been aligned to do what its name might suggest.

  • If an instruction is recognized but offers no useful functionality (for example, if the system has been configured for security reasons so that xsl:evaluate always raises an error), then element-available when applied to that instruction should return false.

For element names in other namespaces:

  • The result of the element-available does not depend on whether or not the namespace of the supplied instruction name has been designated as an extension element namespace; it tests whether the instruction would be available if the namespace were designated as such.

24.2.3 Fallback

<!-- Category: instruction -->
<xsl:fallback>
  <!-- Content: sequence-constructor -->
</xsl:fallback>

The content of an xsl:fallback element is a sequence constructor, and when performing fallback, the value returned by the xsl:fallback element is the result of evaluating this sequence constructor.

When not performing fallback, evaluating an xsl:fallback element returns an empty sequence: the content of the xsl:fallback element is not evaluated.

There are two situations where a processor performs fallback: when an extension instruction that is not available is evaluated, and when an instruction in the XSLT namespace, that is not defined in XSLT 3.0, is evaluated within a region of the stylesheet for which forwards compatible behavior is enabled.

Note:

Fallback processing is not invoked in other situations, for example it is not invoked when an XPath expression uses unrecognized syntax or contains a call to an unknown function. To handle such situations dynamically, the stylesheet should call functions such as system-property and function-available to decide what capabilities are available.

[ERR XTDE1450] When a processor performs fallback for an extension instruction that is not recognized, if the instruction element has one or more xsl:fallback children, then the content of each of the xsl:fallback children must be evaluated; it is a dynamic error if it has no xsl:fallback children.

Note:

This is different from the situation with unrecognized XSLT elements. As explained in 3.10 Forwards Compatible Processing, an unrecognized XSLT element appearing within a sequence constructor is a static error unless (a) forwards compatible behavior is enabled, and (b) the instruction has an xsl:fallback child.