Book HomeXSLSearch this book

4.4. Parameters

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.

4.4.1. Defining a Parameter in a Template

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, "Attribute Value Templates" in Chapter 3, "XPath: A Syntax for Describing Needles and Haystacks".

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.

4.4.2. Passing Parameters

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:

4.4.3. Global Parameters

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.

4.4.3.1. Xalan

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.)

4.4.3.2. XT

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

4.4.3.3. Microsoft's XSLT tools

Microsoft's XSLT tools support external parameters like this:

msxsl xyz.xml params.xsl startX=50 baseColor=magenta

4.4.3.4. Saxon

Saxon supports external parameters like this:

java com.icl.saxon.StyleSheet xyz.xml params.xsl startX=50 baseColor=magenta

4.4.3.5. Oracle

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

4.4.3.6. Setting global parameters in a Java program

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


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.