Refer to the value of a stylesheet parameter in XSLT
Tested with xsltproc on |
Debian (Etch, Lenny, Squeeze) |
Ubuntu (Hardy, Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty, Oneiric, Precise, Quantal) |
Tested with Xalan on |
Debian (Etch, Lenny, Squeeze) |
Ubuntu (Hardy, Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty, Oneiric, Precise, Quantal) |
Tested with Saxon-B on |
Debian (Lenny, Squeeze) |
Ubuntu (Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty, Oneiric, Precise, Quantal) |
Tested with Saxon-6 on |
Debian (Etch, Lenny, Squeeze) |
Ubuntu (Hardy, Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty, Oneiric, Precise, Quantal) |
Objective
Refer to the value of a stylesheet parameter in XSLT
Scenario
Suppose that you are using an XSLT stylesheet to generate the content of a web site. Some of the internal hyperlinks on this site must be in absolute form in order to navigate between pages that do and do not use SSL, however you would prefer not to hard-code the domain name into the stylesheet. You have therefore chosen to present the domain name as a stylesheet parameter when the XSLT processor is invoked. For example:
xsltproc --stringparam domain "www.example.com" style.xsl page.xml
You now want to access this parameter from within the stylesheet. Specifically, you want to construct a link to the login page of the web site composed of the following markup (assuming a domain name of www.example.com
):
<a href="https://www.example.com/login.html">Click here to log in ...</a>
Method
Overview
The method described here has two steps:
- Declare the parameter using an
xsl:param
element. - Refer to the parameter within an XSLT expression.
The following techniques are available if you want to use the parameter in a context that would not otherwise be interpreted as an expression:
- using an
xsl:value-of
element within the body of another element, - using an
xsl:copy-of
element within the body of another element, or - using ‘attribute value template’ syntax.
Declare the parameter using an xsl:param element
Setting a parameter when the XSLT processor is invoked does not by itself make it usable within the stylesheet: it must also be declared by means of an xsl:param
element. This must be placed at the top level of the stylesheet outside of any template declarations, typically at or near the beginning:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:param name="domain"/> <!-- ... --> </xsl:stylesheet>
Note that xsltproc (as of version 1.1.24) does not enforce this requirement, allowing parameters to be used whether or not they have been declared. This behaviour is permitted by the XPath specification, but it is not required, and it is not how the XSLT specification indicates that stylesheet parameters should be used. Most other stylesheet processors (including Xalan and Saxon) report an error under these circumstances.
Refer to the parameter within an expression
A parameter reference consists of a dollar sign followed by the name of the parameter, so in this instance it would have the form:
$domain
Note that this will only have the intended effect when used in a context where it is evaluated as an expression. You will often need to engineer this using one of the techniques described below.
Using a xsl:value-of element within the body of another element
If you want to use the parameter value within the body of an element then that can be arranged by evaluating it within the select
attribute of an xsl:value-of
element:
<xsl:value-of select="$domain"/>
For example, one way to generate the hyperlink described above would be to construct the URL using xsl:value-of
then place it within the body of an xsl:attribute
element:
<a> <xsl:attribute name="href">https://<xsl:value-of select="$domain"/>/login.html</xsl:attribute> Click here to log in ... </a>
Note that xsl:value-of
converts the selected expression into a string before incorporating it into the result tree. If this is not the desired behaviour the xsl:copy-of
should be used instead.
Using a xsl:copy-of element within the body of another element
The xsl:copy-of
element behaves in a similar manner to xsl:value-of
except that it does not convert the selected expression into a string:
<xsl:copy-of select="$domain"/>
In this example there is nothing to be gained by using xsl:copy-of
because the domain name should already be a string (and is needed in the form of a string if it is to become part of an attribute value). In circumstances where the parameter instead becomes part of the content of the result document, it probably makes sense to use xsl:copy-of
in preference to xsl:value-of
to allow for the possibility of using a structured value.
Using attribute value template syntax
When the parameter is to become part of an attribute value, an alternative syntax can be used that is both more concise and more readable:
<a href="https://{$domain}/login.html"> Click here to log in ... </a>
This is an example of an ‘attribute value template’. The section within braces is interpreted as an expression, allowing a parameter reference to be used. There can be several of these within the same attribute value if required.
Be aware that only some types of attribute are interpreted as attribute value templates. These include attributes of literal result elements (as in the example above), and the name
and namespace
attributes of xsl:element
and xsl:attribute
elements. Others instances are detailed in the XSLT specification.
Variations
Specifying a default value for the parameter
Parameters can be given a default value for use when one has not been provided by the XSLT processor. There are two alternative forms that this can take:
- as the
select
attribute of thexsl:param
element, or - as the content of the
xsl:param
element.
Given as a select
attribute, the value is interpreted as an expression. This makes it necessary to use a second set of quotation marks if the value is a string, for example:
<xsl:param name="domain" select="'www.example.com'"/>
Given as the content of the xsl:param
element, the value is interpreted as a sequence constructor (making it similar in form to the content of a template or a literal result element):
<xsl:param name="domain">www.example.com</xsl:param>
Be aware that this will produce a text node containing the specified value, not the value itself. This can make a difference to the outcome in some cases.
In the absence of an explicit default value, parameters default to the empty string. As of XSLT 2 this can be prevented by setting the required
attribute of the xsl:param
element to yes
. It is then an error if the XSLT processor does not supply a value.
Troubleshooting
See: | Troubleshooting XSLT stylesheet parameters |
Tags: xslt