How to Use EXSLT

This page describes how to use the extensions that are available within EXSLT.

Contents

Defining Extension Namespaces

The first step to using the extensions described in EXSLT is to define the relevant namespace for the EXSLT module. You should declare the namespace on the xsl:stylesheet element in your stylesheet.

You can find the namespace that you need to define on the page describing the module for the functions that you want to use. Generally, the namespaces are named in a standard way, though:

http://exslt.org/module-name

For example, you can define the namespace for the Math module with:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math">
...
</xsl:stylesheet>

You can use the extension-element-prefixes attribute to prevent the extension namespaces from being output in the result tree:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
...
</xsl:stylesheet>

Using Named Templates

When it comes down to it, nothing beats a named template for portability. Named templates are pure XSLT 1.0. You don't have to worry about which XSLT processor you're using or what it supports to know that you can use named templates.

Within EXSLT, we try to provide a named template with as near to the equivalent functionality of each extension function as you can get. For example, the math:min function has a pure XSLT 1.0 named template available in math.min.template.xsl. If you are only interested in this template, then you can simply import this stylesheet:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.min.template.xsl" />
...
</xsl:stylesheet>

You can then call the named template with xsl:call-template:

<xsl:call-template name="math:min">
...
</xsl:call-template>

The names of the parameters that should be passed to the template, the effect they have and the default value that's used if you don't supply one are all described alongside the description of the equivalent function.

Using Extension Functions

Extension functions give added functionality to XPath. Some extension functions are built into particular XSLT processors, so if you're using the processor then you can use the function. In other cases, you need to point the processor at an implementation of the function that it can use.

Using Particular Implementations

There are two broad categories of the implementations of extension functions that are available on this site:

Using implementations defined with EXSLT - Functions

The first way to define an implementation of a function is using exsl:function at the top level of your stylesheet. These implementations will only work if the XSLT processor that you use supports EXSLT - Functions.

If you're using one of these processors, all you need to do is to import the EXSLT - Functions stylesheet into your stylesheet. For example, to use the EXSLT - Functions implementation of math:min, copy it to the same directory as your stylesheet and use:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.min.function.xsl" />
...
</xsl:stylesheet>

Using implementations defined in other languages

The second type of implementations are those defined in other languages. With these, you need to use func:script from XSLT 1.1. These implementations will only work if the XSLT processor that you use supports both EXSLT - Functions and the language that you use to implement the function.

If you're using one of these processors, you need a xsl:script element with the following attributes:

  • implements-prefix - the prefix of the module
  • language - the language of the implementation
  • src - the location of the implementation file

For example, to use the JavaScript implementation of math:min, copy it to the same directory as your stylesheet and use:

<xsl:stylesheet version="1.1"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          xmlns:func="http://exslt.org/functions"
          extension-element-prefixes="math func">
<func:script implements-prefix="math" 
      language="exslt:javascript" 
      src="math.min.js" />
...
</xsl:stylesheet>

You can use multiple func:script elements to define multiple implementations of the same function in different languages. However, you cannot use multiple func:script elements to define implementations in the same language of different functions in the same module - it is an error to have multiple func:script elements with the same value for implements-prefix and language in the same stylesheet. If you want to use lots of functions from the same module, you need to merge the files and reference the result with the src attribute.

Using the Function-Level Packages

If you want to use only one particular function, but want to provide a portable stylesheet that can be used with lots of different processors, then you should use the function-level packages that we provide on the site. Each of these packages contains all the implementations that are available for the particular function, plus a stylesheet that draws them all in and makes them available for use.

Making the function available in your stylesheet involves downloading the function-level package, unzipping it and then importing the stylesheet from the package. For example, to make the math:min function available for use in your stylesheet, you should download math.min.zip, unzip it and import math.min.xsl into your stylesheet:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.min.xsl" />
...
</xsl:stylesheet>

This also makes any template implementation of the function available for your use.

Using the Module-Level Packages

If you need to use several functions from a module, then you should use the relevant module-level packages that we provide on the site. Each of these packages contains all the implementations that are available for all the functions in a particular module, plus a stylesheet that draws them all in and makes them available for use.

Making the functions available in your stylesheet involves downloading the module-level package, unzipping it and then importing the stylesheet from the package. For example, to make the EXSLT - Math module available for use in your stylesheet, you should download math.zip, unzip it and import math.xsl into your stylesheet:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:math="http://exslt.org/math"
          extension-element-prefixes="math">
<xsl:import href="math.xsl" />
...
</xsl:stylesheet>

Ensuring Portability with Extension Functions

Whether the extension function you use is built into your processor or is a user-defined extension function, it's good practice to test that the function is supported before you use it. You can test whether a function is available using the function-available function. For example, to test whether math:min is available, you can use the test:

function-available('math:min')

The function-level and module-level packages that we supply here usually include a definition of a named template that has equivalent functionality to the function, so even if a processor doesn't support any of the implementation languages, you can still fall back on the named template to get the functionality you're after. For example, for maximum portability in printing out the minimum of a set of values, I should use:

<xsl:choose>
   <xsl:when test="function-available('math:min')">
      <xsl:value-of select="math:min($values)" />
   </xsl:when>
   <xsl:otherwise>
      <xsl:call-template name="math:min">
         <xsl:with-param name="nodes" select="$values" />
      </xsl:call-template>
   </xsl:otherwise>
</xsl:choose>

Using Extension Elements

Extension elements give added functionality to XSLT. There is no standard way at the moment to point a processor at an implementation of an extension element so that it can use it. Instead, the processor you use must have built-in support of the extension element.

There are two ways that you can make sure that your stylesheet doesn't break when you use an extension element. First, you can test whether the element is available with the element-available function. For example, to test whether the grp:group element is available, you can use:

<xsl:choose>
   <xsl:when test="element-available('grp:group')">
      <grp:group ...>
         ...
      </grp:group>
   </xsl:when>
   <xsl:otherwise>
      <xsl:message terminate="yes">
         ERROR: Your processor does not support grp:group
      </xsl:message>
   </xsl:otherwise>
</xsl:choose>

In some processors (in particular Saxon), this only works if the element has been categorised as an instruction; it does not work for top-level elements.

The second way of making sure that the stylesheet doesn't break when you use an extension element is to use the xsl:fallback element. If you've declared that an element is an extension element by giving its namespace through one of the prefixes in the extension-element-prefixes attribute on xsl:stylesheet, and the processor comes across it in a template but doesn't have a built-in implementation of it then the processor will perform fallback. Fallback involves looking for an xsl:fallback element in the content of the extension element, and instantiating its content. For example, the following tries to use the extension element grp:group and supplies an error message if the extension element is not there.

<grp:group ...>
   ...
   <xsl:fallback>
      <xsl:message terminate="yes">
         ERROR: Your processor does not support grp:group
      </xsl:message>
   </xsl:fallback>
</grp:group>

This will only work with extension elements used within templates.

http://www.exslt.org/howto.html