Using XML Queries and Transformations

Variables and Parameters

Once you have read this section, you will have found out that its title is a bit deceptive. You, as a programmer, have certain expectations about a new programming language when you start learning it. One of them is that you expect it to be possible to store values in variables, change them and retrieve them later. Although XSLT has an element called variable, you actually cannot do much with it. This may sound unbelievable, but it is a result of the way XSLT works that you cannot have variables. This is a thing that beginner XSLT programmers have many difficulties grasping.

variable

A variable in XSLT is really not what we would call a variable in VB, but more like a constant. The syntax for declaring a variable is like this:

<xsl:variable name="x" select="2"/>

Or you can declare it like this:

<xsl:variable name="x">2</xsl:variable>

These syntaxes are equivalent, but note that the first example uses an XPath expression and the second one uses an included fragment of XML. This causes the first variable to hold the numeric value 2 and the second one the string value '2'.

The value of a variable can be used in expressions and attribute value templates. The reference to a variable's value is done with $variablename, for example:

<xsl:variable name="x" value="2"/>
...
<xsl:value-of select="item[$x]"/>
<xsl:variable name="author">
Teun Duynstee
</xsl:variable>
...
<xsl:copy-of select="$author"/>

The copy-of element is a convenient way to insert the value of a variable into the output document.

A variable can be used both as a top-level element (child of the stylesheet element) and at template level (descendant of a template element). As a top-level element, the variable can be used from any place in the document. Within the template, the variable can be seen by all elements following the declaration (and their descendants).

In conclusion, the variable element doesn't really live up to its name, because it cannot change. There is no way to change the content. This is done by design. The XSLT specification does not want to specify any order for the evaluation of different nodes. By introducing changing values, it would become relevant for the result whether a certain action is performed before or after the change.

param

The param element works very much like the variable element. The param element has a name attribute and a select attribute, but the select attribute on the param element is only a default value. If a value is passed, this replaces the value in the select attribute.

Passing a Parameter to a Template

If a template has a parameter defined, a value can be passed when the template is executed (by apply-templates or call-template). Suppose you have this template:

<xsl:template name="numbered-item">
<xsl:param name="format" select="1. "/>
  <xsl:number format="{$format}"/>
<xsl:apply-templates/>
</xsl:template>

If you call it using call-template, its index number would be formatted numerically (1. ). But we could also have the same template output the number in another format using the parameter format (which is used in the attribute value template in the number element):

<xsl:template match="OL/LI"><xsl:call-template name="numbered-item">
  <xsl:if test="@count = 'alpha'">
    <xsl:with-param name="format" select="'a. '"/>
  </xsl:if>
</xsl:call-template>
</xsl:template>

This template will match on LI elements that have an OL parent. The transformation of these elements is implemented in the template 'numbered-item'. Only if the matched element has a count attribute with value 'alpha' does the template get called with a passed parameter value. This will cause the called template to output the number of the element in another format.

The with-param element can be used as a child of call-template and apply-templates. The name must be specified; the value can also be specified with the content of the element (just like the variable and param elements can).

Passing a Parameter to a Stylesheet

Although the XSLT specification defines a way to declare global parameters, nothing is mentioned about passing a parameter to the stylesheet. This depends on the implementation of the library you use. The SAXON and XT implementations both allow passing parameters on the command line. In the developers preview of MSXML, you can set a parameter to a stylesheet only by using the special XMLDOMXSLProcessor object. This object is new in the MSXML library and is intended to cache compiled stylesheets to improve performance for repeated transforms with the same stylesheet. If your stylesheet contains a parameter called $x, the following code could be used to make the transformation:

Dim oDoc as new MSXML2.DOMDocument
Dim oXSLT as new MSXML2.DOMDocument
Dim oResult as new MSXML2.DOMDocument
Dim oTemplate as new MSXML2.XSLTemplate
Dim oXMLDOMXSLProcessor as new MSXML2.XMLDOMXSLProcessor
oDoc.async = false
oXSLT.async = false
oDoc.load "http://www.comp.com/sourceDocument.xml"
oXSLT.load "http://www.comp.com/stylesheet.xsl"

Set oTemplate.stylesheet = oXSLT.documentElement
Set oXMLDOMXSLProcessor = oTemplate.createProcessor
Set oXMLDOMXSLProcessor.input = oDoc
Set oXMLDOMXSLProcessor.output = oResult

oXMLDOMXSLProcessor.addParameter("x", "Value we want to pass in")
oXMLDOMXSLProcessor.transform

There are quite a lot of objects that we need here, three DOMDocument objects for starters. One of them may be empty. It is the target for the transform (oResult). The second one contains the source document (oDoc) and the third one contains the stylesheet (oXSLT). oXSLT is used to build the right template object. This template is used to create an XMLDOMXSLProcessor object. We inform the processor about the input and output documents, and then finally add our parameter value and let it transform. As this library is by no means stable at the time of writing – it is only a preview after all – it is very possible (so indicates the preliminary documentation) that the syntax will be different in the final release. In any case, the functionality of passing parameters will be included in that release.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“XML is like violence - if it's not working for you, you're not using enough of it.”