This tip uses the Apache Project's Xalan Java 2 transformation
engine and its implementation (see Resources). The overall concepts are the same for any
implementation, but the XSLT recommendation doesn't mandate any particular
implementation method. In addition to Xalan, you will need the js.jar file (see Resources), which contains an
as well as
bsf.jar, which is part of the Xalan
The source document
The example style sheet documents the entries in a guessing game, where players make three guesses of 1 to 100. The style sheet takes those three guesses and compares them to random numbers. The sample document contains two sets of guesses:
The sample document
<?xml version="1.0"?> <entries gameID="DWO"> <entry> <player>John</player> <guess>3</guess> <guess>9</guess> <guess>222</guess> </entry> <entry> <player>Mary</player> <guess>88</guess> <guess>76</guess> <guess>5</guess> </entry> </entries>
Create the component
The first step in using an extension element or function is to define the code to be executed. This involves defining a new namespace and a container for the code:
The basic style sheet
On the surface, this is a typical style sheet, with the
addition of two new namespaces. The first, with the prefix
tells the processor which elements define the new functionality. The second,
result, indicates a call to the new functionality.
attribute lets the processor know which elements should not be transformed as
part of the normal flow. (They can
still return a value to be output, as we'll see.)
The component itself specifies that all the code within it
will be called from the
prefix. It also lets the processor know which functions will be called from
extension elements, and which from extension functions. The script element
describes the functions themselves.
In this case, we're starting with a function that takes an argument and compares it to a random number from 1 to 100, returning a string that signifies the result.
In an XSLT style sheet, extension functions actually extend
XPath so you can use them just as you would a built-in function such as
Calling a function
... <xsl:template match="/"> <xsl:apply-templates/> </xsl:template> <xsl:template match="entry"> Guesser: <xsl:value-of select="player"/> <xsl:apply-templates select="guess"/> </xsl:template> <xsl:template match="guess"> Guess: <xsl:value-of select="."/> Actual: <xsl:value-of select="result:getResult(string(.))"/> </xsl:template> </xsl:stylesheet>
This example passes the
string value of the current node (
guess) to the
getResult() function. The namespace lets the processor know
to trigger the function in the result component.
Figure 1. Preliminary results
Using an element
Extension elements are a bit more complex than functions. Rather than simply returning a value (although they can), they are intended to execute a particular action at a particular "time" within the processing of the style sheet. Also, rather than taking an arbitrary list of arguments, as an extension function can, the code behind an extension element has two well-defined arguments.
triggers the processing of the
function. This function takes as one of its
rules element itself (
elem), allowing you to retrieve the value of any custom attribute it carries.
Using the processor context
Perhaps the most powerful aspect of an extension element is its ability to access the source document itself through the XSL processor context argument.
The processor context
The first argument of the
function is the processor context, in the form of the
object. This allows you to retrieve objects
that represent the context node, the overall source tree, the style sheet, and
the transformer currently performing the transformation. Accessing the context
node is most common. Once returned by the
method, this is a typical XML node, with typical
DOM operations available.
Figure 2. The final output
- Check out the XSLT recommendation from the W3C.
- Download Apache's Xalan-Java 2.
- Download the js.jar file.
- Find more XML resources on the developerWorks XML zone.
- IBM trial software: Build your next development project with trial software available for download directly from developerWorks.