The XSLT <xsl:param>
and <xsl:with-param>
elements allow you to pass parameters to a template. You can pass templates with either the <call-template>
element or the <apply-templates>
element; we’ll discuss the details in this section.
To define a parameter in a template, use the <xsl:param>
element. Here’s an example of a template that defines two parameters:
<xsl:template name="calcuateArea"> <xsl:param name="width"/> <xsl:param name="height"/> <xsl:value-of select="$width * $height"/> </xsl:template>
Conceptually, this is a lot like writing code in a traditional programming language, isn’t it? Our template here defines two parameters, width
and height
, and outputs their product.
If you want, you can define a default value for a parameter. There are two ways to define a default value; the simplest is to use a select
attribute on the <xsl:param>
element:
<template name="addTableCell"> <xsl:param name="bgColor" select="'blue'"/> <xsl:param name="width" select="150"/> <xsl:param name="content"/> <td width="{$width}" bgcolor="{$bgColor}"> <xsl:apply-templates select="$content"/> </td> </template>
In this example, the default values of the parameters bgColor
and width
are 'blue'
and 150
, respectively. If we invoke this template without specifying values for these parameters, the default values are used. Also notice that we generated the values of the width
and bgcolor
attributes of the HTML <td>
tag with attribute value templates, the values in curly braces. For more information, see Section 3.3 in Chapter 3.
Warning
Notice that in the previous sample, we put single quotes around the value blue
, but we didn’t do it around the value 150
. Without the single quotes around blue
, the XSLT processor assumes we want to select all the <blue>
elements in the current context, which is probably not what we want. The XSLT processor is clever enough to realize that the value 150
can’t be an XML element name (the XML 1.0 Specification says element names can’t begin with numbers), so we don’t need the single quotes around a numeric value.
Try to keep this in mind when you’re using parameters. You’ll probably forget it at some point, and you’ll probably go nuts trying to figure out the strange behavior you’re getting from the XSLT processor.
The second way to define a default value for a parameter is to include content inside the <xsl:param>
element:
<template name="addTableCell"> <xsl:param name="bgColor"> <xsl:text>blue</xsl:text> </xsl:param> <xsl:param name="width"> <xsl:value-of select="7+8"/><xsl:text>0</xsl:text> </xsl:param> <xsl:param name="content"/> <td width="{$width}" bgcolor="{$bgColor}"> <xsl:apply-templates select="$content"/> </td> </template>
In this example, we used <xsl:text>
and <xsl:value-of>
elements to define the default values of the parameters. Out of sheer perverseness, we defined the value of width
as the concatenation of the numeric expression 7+8
, followed by the string “0”. This example produces the same results as the previous one.
If we invoke a template by name, which is similar to calling a subroutine, we’ll need to pass parameters to those templates. We do this with the <xsl:with-param>
element. For example, let’s say we want to call a template named draw-box, and pass the parameters startX
, startY
, endX
, and endY
to it. Here’s what we’d do:
<xsl:call-template name="draw-box"> <xsl:with-param name="startX" select="50"/> <xsl:with-param name="startY" select="50"/> <xsl:with-param name="endX" select="97"/> <xsl:with-param name="endY" select="144"/> </xsl:call-template>
In this sample, we’ve called the template named draw-box with the four parameters we mentioned earlier. Notice that up until now, <xsl:call-template>
has always been an empty tag; here, though, the parameters are the content of the <xsl:call-template>
element. (If you want, you can do the same thing with <xsl:apply-templates>
.) We used the <xsl:with-param>
element with the <xsl:call-template>
element here, but you can also use it with <xsl:apply-templates>
.
If we’re going to pass parameters to a template, we have to set up the template so that it expects the parameters we’re passing. To do this, we’ll use the <xsl:param>
element inside the template. Here are some examples:
<xsl:template name="draw-box"> <xsl:param name="startX"/> <xsl:param name="startY" select="'0'"/> <xsl:param name="endX"> 10 </xsl:param> <xsl:param name="endY"> 10 </xsl:param> ... </xsl:template>
A couple of notes about the <xsl:param>
element:
If you define any
<xsl:param>
elements in a template, they must be the first thing in the template.The
<xsl:param>
element allows you to define a default value for the parameter. If the calling template doesn’t supply a value, the default is used instead. The last three<xsl:param>
elements in our previous example define default values.The
<xsl:param>
element has the same content model as<xsl:variable>
. With no content and no select attribute, the default value of the parameter is an empty string (""
). With a select attribute, the default value of the parameter is the value of the select attribute. If the<xsl:param>
element contains content, the default value of the parameter is the content of the<xsl:param>
element.
XSLT allows you to define parameters whose scope is the entire stylesheet. You can define default values for these parameters and you can pass values to those parameters externally to the stylesheet. Before we talk about how to pass in values for global parameters, we’ll show you how to create them. Any parameters that are top-level elements (any <xsl:param>
elements whose parent is <xsl:stylesheet>
) are global parameters. Here’s an example:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text"/> <xsl:param name="startX"/> <xsl:param name="baseColor"/> <xsl:variable name="newline"> <xsl:text> </xsl:text> </xsl:variable> <xsl:template match="/"> <xsl:value-of select="$newline"/> <xsl:text>Global parameters example</xsl:text> <xsl:value-of select="$newline"/> <xsl:value-of select="$newline"/> <xsl:text>The value of startX is: </xsl:text> <xsl:value-of select="$startX"/> <xsl:value-of select="$newline"/> <xsl:text>The value of baseColor is: </xsl:text> <xsl:value-of select="$baseColor"/> <xsl:value-of select="$newline"/> </xsl:template> </xsl:stylesheet>
How you pass values for global parameters depends on the XSLT processor you’re using. We’ll go through some examples here for all the usual suspects. Let’s say we want to pass the numeric value 50
as the value for startX
, and the string value magenta
as the default value for baseColor
. Here are the commands you’d use to do that.
To pass global parameters to Xalan, you can define them on the Xalan command line:
java org.apache.xalan.xslt.Process -in xyz.xml -xsl params.xsl -param startX 50 -param baseColor magenta
(This command should be on a single line.)
If you’re using James Clark’s XSLT processor, you can pass parameters like this:
java com.jclark.xsl.sax.Driver xyz.xml params.xsl startX=50 baseColor=magenta
Microsoft’s XSLT tools support external parameters like this:
msxsl xyz.xml params.xsl startX=50 baseColor=magenta
Saxon supports external parameters like this:
java com.icl.saxon.StyleSheet xyz.xml params.xsl startX=50 baseColor=magenta
If you’re using Oracle’s parser, stylesheet parameters are passed like this:
java oracle.xml.parser.v2.oraxsl -p startX=50 -p baseColor='magenta' xyz.xml params.xsl
(This command should be on a single line.) Notice that for the Oracle parser, we had to put single quotes around the text value magenta
.
Using this stylesheet with any XML document and any of the XSLT processors listed here produces these results:
Global parameters example The value of startX is: 50 The value of baseColor is: magenta
If your XSLT engine supports the Transformation API for XML (TrAX), you can embed the XSLT processor and set global parameters in your code. Here’s an example that uses TrAX support:
import java.io.File; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; public class GlobalParameters { public static void parseAndProcess(String sourceID, String xslID, String outputID) { try { TransformerFactory tfactory = TransformerFactory.newInstance(); Transformer transformer = tfactory.newTransformer(new StreamSource(xslID)); // Use the setParameter method to set global parameters transformer.setParameter("startX", new Integer(50)); transformer.setParameter("baseColor", "magenta"); transformer.transform(new StreamSource(new File(sourceID)), new StreamResult(new File(outputID))); } catch (TransformerConfigurationException tce) { System.err.println("Exception: " + tce); } catch (TransformerException te) { System.err.println("Exception: " + te); } } public static void main(String argv[]) throws java.io.IOException, org.xml.sax.SAXException { GlobalParameters gp = new GlobalParameters(); gp.parseAndProcess("xyz.xml", "params.xsl", "output.text"); } }
Notice that we used the setParameter
method to set global parameters for the Transformer
object before we invoke the transform
method. This transformation generates the following results in output.text
:
Global parameters example The value of startX is: 50 The value of baseColor is: magenta
Get XSLT now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.