XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (221 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
5.52Mb size Format: txt, pdf, ePub

refer to the same namespace URI. If the name has no prefix then it has a null namespace URI—it does not use the default namespace URI.

Parameter names are referenced in exactly the same way as variables, by prefixing the name with a dollar sign (for example,
$num
) and all the rules for uniqueness and scope of names are exactly as if the

element was replaced by an

element. The only difference between parameters and variables is the way they acquire an initial value.

Tunnel Parameters

Tunnel parameters are a new facility in XSLT 2.0. If a tunnel parameter is passed to a template when it is called, then it is automatically passed on to any further templates called from this template. For example, if template A creates a tunnel parameter and passes it on a call to template B, then when B calls C and C calls D, the tunnel parameter will be passed transparently through all these calls and will be accessible to template D, even if B and C were quite unaware of the parameter.

This feature is very useful when you are customizing a stylesheet. Suppose that D is a template rule that formats equation numbers in Roman numerals, and you want to use Greek letters instead. You can write a customization layer (an importing stylesheet) that overrides D with a template rule of your own. But suppose you want D sometimes to use Greek letters and sometimes Roman numerals, how do you pass it this information? Global variables only solve the problem if the choice is constant for all invocations of D during the course of a transformation. Adding parameters to every template en route from your top-level A template to the D template would require overriding lots of template rules in the base stylesheet, which you want to change as little as possible. So the answer is that you write a customized version of the A template that sets a tunnel parameter, and a customized version of D that reads the tunnel parameter, and the intermediate templates B and C don't need to be changed.

The theory behind tunnel parameters is the concept of dynamically scoped variables in functional programming languages such as Lisp.

A tunnel parameter always starts life in an

element. This may be on any kind of template call that allows parameter passing: specifically,

,

,

, and

. For example:


  

    

  

  

    

  


I've put the parameter name in a namespace here, to minimize the risk that it will clash with a parameter added by someone else.

This tunnel parameter will be passed silently up the call stack, through all calls of

,

,

, and

, until it reaches a template that is interested in it. This template can declare its interest by including the parameter declaration:


and can then use the parameter value in the normal way, by referring to it as
$mq:format-greek
within an XPath expression.

Tunnel parameters are not passed through XPath function calls, so if the stylesheet evaluates an XPath expression which calls a stylesheet function, which in turn calls

, then the tunnel parameters will not be accessible in this call. Similarly, they are not available when an attribute set is expanded.

At the point where the parameter enters the tunnel (the

element), it must have a name that differs from all the other sibling

elements, whether these are tunnel parameters or not. Similarly, when it emerges from the tunnel (the

element), it must have a name that differs from other

elements in that template. But where it is being silently passed through intermediate templates, name clashes don't matter: silently passed tunnel parameters are in effect in a different symbol space from explicit parameters.

Tunnel parameters can be of any type. They can be optional or required parameters, and if optional, the receiving template can declare a default value. Reading the tunnel parameter in this way isn't destructive; it will still be passed on to further templates. Specifying a required type or a default value doesn't change the value that is passed on; for example, if the original value is a node, and the receiving template declares it as a string, then the node will be atomized for the purposes of the receiving template, but the value that's passed on will still be a node, unless a new

element is used to change the value.

Usage

The different kinds of parameters (stylesheet parameters, template parameters, and tunnel parameters) can be used in different ways. These are discussed in the following sections.

Using Stylesheet Parameters

Stylesheet parameters can be used in various ways to control the actions performed by the transformation. For example, they are particularly useful for selecting which part of the source document to process. A common scenario is that the XSLT processor will be running within a Web server. The user request will be accepted by an application: perhaps a Java Server Page, a Java servlet, or an ASP or PHP page. The request parameters will be read, and the stylesheet processing will be kicked off using an API defined by each vendor. Generally, this API will provide some way of passing the parameters that came from the HTTP request into the stylesheet as the initial values of global

elements.

If the stylesheet is running interactively in the browser, it will typically be invoked using a JavaScript API, which again will accept data from the user and pass it to the stylesheet in the form of parameter values.

If the API supports it, a global parameter may take a value of any type: not just a string, number, or boolean, but also a node or sequence of nodes. In some cases the API allows the parameter to be supplied in the form of an XPath expression, which is evaluated to generate the actual parameter value. Because the value can contain nodes, this provides another way of supplying secondary source documents for use by the stylesheet, as an alternative to the
document()
function. Many products allow such a parameter to be supplied as a DOM
Document
object.

Where a stylesheet needs to get system-dependent information (for example, the name of the user, or the operating system version number), it is often much easier to pass the information as a stylesheet parameter rather than writing extension functions to deliver the information on request.

Wherever you define a global variable, ask yourself whether it would be better to make it a stylesheet parameter instead. The default value of a stylesheet parameter can be used in exactly the same way as a global variable; the only difference is that you have added the ability for the user to change the value from outside. Also, remember that when one stylesheet module imports another, the importing module can override an

in the imported module with an

, or vice versa.

The new facilities in XSLT 2.0 to declare a stylesheet parameter with
required=“yes”
, and to declare its required type, make stylesheet parameters a lot more robust than they were. There are still a few loopholes, however—there is no rule that prevents an importing module redefining a parameter by changing its type in arbitrary ways, or changing the setting to
required=“no”
.

Other books

The Final Page of Baker Street by Daniel D. Victor
Alfred Hitchcock by Patrick McGilligan
Fever Dream by Annabel Joseph
The North: A Zombie Novel by Cummings, Sean