xsl:template


The <xsl:template> element defines a template for producing output. It may be invoked either by matching nodes against a pattern, or explicitly by name .

Changes in 2.0

It is now possible to define a template rule that matches in multiple modes.

The new as attribute allows the type of the result to be defined. Moreover, the new <xsl:sequence> instruction means that a template can now return atomic values and references to existing nodes; it is no longer limited to constructing new nodes.

The syntax for patterns has been extended so that a template rule can now match nodes according to their schema-defined type. The match pattern may also now contain references to global variables or parameters.

Nonsensical combinations of attributes are now considered to be errors, for example, specifying priority or mode when there is no match attribute. In XSLT 1.0, such attributes were ignored.

Format

 <xsl:template   match? = pattern   name? = qname   priority? = number   mode? = tokens   as? = sequence-type>   <!-- Content: (xsl:param*, sequence-constructor) --> </xsl:template> 

Position

<xsl:template> is a declaration, which means that it always appears as a child of the <xsl:stylesheet> element.

Attributes

Name

Value

Meaning

match

optional

Pattern

A pattern that determines which nodes are eligible to be processed by this template. If this attribute is absent, there must be a name attribute

name

optional

lexical QName

The name of the template. If this attribute is absent, there must be a match attribute

priority

optional

Number

A number (positive or negative, integer or decimal) that denotes the priority of this template, and is used when several templates match the same node

mode

optional

list of mode names , or «#all »

The mode or modes to which this template rule applies. When <xsl:apply-templates> is used to process a set of nodes, the only templates considered are those with a matching mode

as

optional

SequenceType

The type of the sequence produced when this template is evaluated. A type error is reported if the result does not match this type

The construct Pattern is defined in Chapter 6. The construct SequenceType is defined in Chapter 4, and more completely in 4 XPath 2.0 Programmer's Reference .

The mode and priority attributes must not be specified unless the match attribute is also specified.

Content

Zero or more <xsl:param> elements, followed by a sequence constructor.

Effect

There must be either a match attribute, or a name attribute, or both.

  • If there is a match attribute, the <xsl:template> element defines a template rule that can be invoked using the <xsl:apply-templates> instruction.

  • If there is a name attribute, the <xsl:template> element defines a named template that can be invoked using the <xsl:call-template> instruction.

  • If both attributes are present, the template can be invoked in either of these ways.

The match Attribute

The match attribute is a Pattern , as defined in Chapter 6. The pattern is used to define which nodes this template rule applies to.

When <xsl:apply-templates> is used to process a selected set of nodes, each node is processed using the best-fit template rule for this node, as described under <xsl:apply-templates> on page 187.

A template is only considered a candidate if the node matches the pattern supplied in the match attribute and if the value of the mode attribute matches the mode attribute of the <xsl:apply-templates> instruction (as described below on page 454).

If more than one template rule meets these criteria, they are first considered in order of import precedence (as described under <xsl:import> on page 314), and only templates with the highest import precedence are considered further.

If there is still more than one template rule (in other words, if two template rules that both match the node have the same import precedence), they are next considered in order of priority. The priority is either given by the value of the priority attribute, described below, or is a default priority that depends on the match pattern. The rules for determining the default priority of any pattern are given in Chapter 6, on page 498.

If this leaves one pattern with a numerically higher priority than all the others, this one is chosen . If there are several with the same priority, which is higher than all the others, the XSLT processor has the choice of reporting an error, or choosing from the remaining templates the one that appears last in the stylesheet. Several processors in practice report a warning, which you can ignore if you wish. In my experience, however, this condition often indicates that the stylesheet author has overlooked something.

XSLT 2.0 allows the pattern to contain a reference to a global variable or parameter. This allows a pattern such as «match="part[@number=$param]" » , which means that the same pattern will match different nodes on different runs of the stylesheet. But there are rules to prevent circular definitions: Evaluating the variable must not invoke an <xsl:apply-templates> instruction, either directly or indirectly.

The name Attribute

The name attribute is a lexical QName ; that is, a name optionally qualified with a namespace prefix. If there is a prefix, it must correspond to a namespace declaration that is in scope on this element (which means it must be defined either on this element itself, or on the <xsl:stylesheet> element). If there is no prefix, the namespace URI is null; the default namespace is not used.

This name is used when the template is invoked using <xsl:call-template> . The name attribute of the <xsl:call-template> element must match the name attribute of the <xsl:template> element. Two names match if they have the same local part and the same namespace URI, but the prefix can be different.

If there is more than one named template in the stylesheet with the same name, the one with higher import precedence is used; for details, see <xsl:import> on page 312. It is an error to have two templates in the stylesheet with the same name and the same import precedence, unless there is another one with the same name and a higher import precedence. This is an error even if the template is never called.

The priority Attribute

The priority attribute is a number, for example «17 » , «0.5 » , or «-3 » : more specifically , an xs:decimal as defined in XML Schema, which allows an optional leading minus sign.

The priority attribute is used to decide which template to invoke when <xsl:apply-templates> is called and there are several possible candidates. For each node selected by the <xsl:apply-templates> instruction, a template rule is chosen using the following procedure:

  • First select all the templates that have a match attribute.

  • From these, select all the templates that match the mode that is used on the call of <xsl:apply-templates> . An <xsl:apply-templates> instruction uses either a specific mode (identified by a QName ), or the default mode (which is unnamed) or it can specify «#current » , in which case it uses whatever mode is the current mode at the time. An <xsl:template> element can specify a list of modes that it matches (which can include «#default » to indicate that it matches all modes), or it can specify «#all » to indicate that it matches all modes; if it has no mode attribute, then it matches only the default mode.

  • From these, select all those whose pattern matches the selected node.

  • If there is more than one, select those that have the highest import precedence.

  • If there is still more than one, select those that have the numerically highest priority.

If there are several matching templates left, and they all have the same import precedence and priority, the XSLT processor can either choose the one that occurs last in declaration order, or report an error. Import precedence and declaration order are described under <xsl:import> on page 312.

If there are no templates that match the selected node, the built-in template for the relevant node kind is used. Built-in templates are described under <xsl:apply-templates> on page 190.

The rules for determining the default priority for a pattern are given in Chapter 6, on page 498.

Although the default priorities are carefully chosen, they do not guarantee that a highly selective pattern will always have higher priority than a less selective pattern. For example, the patterns «section/para » and «section/para[1] » both have priority +0.5. Similarly, the patterns «attribute(*, xs:integer) » and «attribute(*, xs:decimal) » have the same priority, even though the nodes that match the first pattern are a subset of those that match the second. Choosing your own priorities is therefore a more reliable approach.

The mode Attribute

If the <xsl:template> element has no mode attribute, then it applies only to the default (unnamed) mode, and will be invoked only in response to an <xsl:apply-templates> instruction that uses the default mode. An <xsl:apply-templates> instruction uses the default mode if it has no mode attribute, if its mode attribute has the value «#default » , or if its mode attribute has the value «#current » and the current mode is the default mode. The concept of the current mode is explained on page 498.

If the mode attribute is present and has the value «#all » , then the template is applicable to all modes.

The mode attribute may also contain a list of modes to which the template is applicable. Each mode is written either as a lexical QName (the actual mode name), or as the token «#default » to indicate that the template is applicable to the default mode.

Mode names are compared using the usual rules for QNames; both names are expanded using the namespace declarations in effect on their respective stylesheet elements (not including any default namespace declaration), and they match if the local name and namespace URI both match.

The mode specified on the <xsl:template> template is not automatically propagated to any <xsl:apply-templates> elements within its body. Although it is common practice to process an entire subtree in a single mode, and therefore for a template to continue using the mode it was called in, this is not the default behavior except in the case of built-in templates. However, the current mode can be propagated by explicitly calling <xsl:apply-templates mode="#current"/> .

If you have a mode attribute on a template and there is no <xsl:apply-templates> element with a matching mode anywhere in the stylesheet, this is not an error, though it means the template will never be selected by any <xsl:apply-templates> call. This can be a handy way of commenting out a template rule.

Evaluating a Template

Once an <xsl:template> element is selected for processing, the following occurs:

  • If called using <xsl:apply-templates> , the context node, context position, and context size are set up as required.

  • A new stack frame is allocated, to hold a new instance of each local variable defined within the template.

  • All parameters listed in <xsl:param> elements contained within the <xsl:template> element are evaluated. These <xsl:param> elements must come before any instructions in the content of the template. For each parameter, if a value was supplied by the caller (using an <xsl: with-param > element with matching name), this value is assigned to the parameter. If necessary, the supplied values are converted to the required type specified in the as attribute, using the standard conversion rules described on page 476. If the supplied value has the wrong type, an error is reported. If no value was supplied by the caller, then if the <xsl:param> element specifies «required="yes" » an error is reported; otherwise the default value of the parameter is evaluated. This process is explained in more detail under <xsl:param> on page 392.

  • The sequence constructor is evaluated. This means that the child instructions of the <xsl:template> element are evaluated in turn . XSLT instructions and extension elements are processed using their individual rules; literal result elements and text nodes are written to the result sequence.

  • The result of evaluating the sequence constructor is checked against the type given in the as attribute of the <xsl:template> element, if any. If necessary, the value is converted to the required type using the standard conversion rules given on page 476. If the value has the wrong type, a fatal error is reported.

When processing of the sequence constructor is complete, the stack frame containing its local variables is deleted, control returns to the calling template, and the context item, position, and size revert to their previous values. The value produced by evaluating the sequence constructor becomes the return value of the calling <xsl:apply-templates> , <xsl:call-template> , <xsl: apply-imports > , or <xsl:next-match> instruction. (If the calling instruction was <xsl:apply-templates> , the value is combined with the values delivered by the template rules for other selected nodes.)

The implementation, of course, is free to do things in a different order if it has the same effect. Some products use lazy evaluation, where the parameters are only evaluated when they are first used. Some products also use tail-call optimization, where a recursive template call is deferred until after the stack has been unwound: This reduces the risk of running out of stack space when calls are deeply nested. Such optimizations may show up if you use extension functions that have side effects, or if you use <xsl:message> to trace the sequence of execution.

Usage and Examples

We will look first at using template rules, and then I will give some advice on the use of modes. For examples of the use of named templates, see <xsl:call-template> on page 220.

Using Template Rules

A template rule is an <xsl:template> element with a match attribute, which can therefore be invoked using the <xsl:apply-templates> instruction.

This rule-based approach to processing is the characteristic way of writing XSLT stylesheets, though it is by no means the only way. Its biggest advantage is that the output for each element type can be defined independently of the context that the element appears in, which makes it very easy to reuse element types in different contexts, or to add new element types to an existing document definition without rewriting the stylesheet templates for all the possible containing elements. A classic example of this approach to processing arises when converting semantic markup in a document to rendition markup, as the following example demonstrates .

Template Rules
start example

This example shows a typical use of template rules to handle narrative text with a free-form structure.

Source

The source file is soloist.xml .

In this text featuring the work of a singer , the name of a composer is tagged <composer> , the title of a musical work is tagged <work> , and the name of a publication is tagged <publication> . Sections of text relating to the same performance are marked with a <performance> tag. So a fragment of marked up text might read:

  <cv>   <para>   <performance>   <publication>Early Music Review</publication> said of his debut   <venue>Wigmore</venue> concert with <group>Ensemble   Sonnerie</group> in <date>1998</date>: <quote>0ne of the   finest concerts I have ever heard ... a singer to watch out for</quote>.   </performance>   <performance>   Other highlights include a televised production of   <composer>Bach</composer> ' s <work>St. Matthew Passion</work> conducted by   <artist>Jonathan Miller</artist>, in which he played <role>Judas</role>.   </performance>   </para>   </cv>  

Stylesheet

The stylesheet file is soloist.xsl .

In presenting this text to a human reader, the main task is to select typographical conventions to be used for each piece of semantic markup. The designer might choose, for example, to display the titles of works in italics, titles of publications in a sans serif font, and composers' names in the ordinary paragraph font. This could be achieved by the following stylesheet definitions ( assuming the output is HTML):

  <xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:template match="/">   <html><body>   <xsl:apply-templates/>   </body></html>   </xsl:template>   <xsl:template match="para">   <p><xsl:apply-templates/></p>   </xsl:template>   <xsl:template match="publication">   <font face="arial"><xsl:apply-templates/></font>   </xsl:template>   <xsl:template match="quote">   <xsl:text/>"<xsl:apply-templates/>"<xsl:text/>   </xsl:template>   <xsl:template match="work">   <i><xsl:apply-templates/></i>   </xsl:template>   <xsl:template match="role">   <u><xsl:apply-templates/></u>   </xsl:template>   </xsl:stylesheet>  

Note that some of the markup is ignored, for example <artist> . The default template for elements simply discards the tags and outputs the text, which is exactly what we want here.

Output

If the generated HTML is copied into a word processor, it will look like Figure 5-14.

start figure

Early Music Review said of his debut Wigmore concert with Ensemble Sonnerie in 1998: "One of the finest concerts I have ever heard ... a singer to watch out for". Other highlights include a televised production of Bach's St. Matthew Passion conducted by Jonathan Miller, in which he played Judas.

end figure

Figure 5-14
end example
 

The great advantage of this approach is that the rules are written making no assumptions about the way the markup tags are nested in the source document. It is very easy to add new rules for new tags, and to reuse rules if an existing tag is used in a new context.

With document structures where the nesting of elements is more rigid, for example in some data interchange files, this very flexible rule-based (or push ) style of processing may have fewer benefits, and a pull programming style using conventional flow-of-control constructs such as <xsl:for-each> , <xsl:if> , and <xsl:call-template> may be preferable. For further discussion of the different design approaches, see Chapter 9.

Using Modes

The classic reason for using modes is to enable the same content to be processed more than once in different ways: For example, the first pass through the document might generate the table of contents, the second pass the actual text, and the third pass an index.

Using modes
start example

The source document is a biography of a singer, in the same format as in the previous example. This time, however, the requirement is to produce at the end of the biography a list of works mentioned in the text.

Source

The source file is soloist.xml . See previous example.

Stylesheet

The stylesheet file is soloist+index.xsl .

This stylesheet extends the previous one using <xsl:import> . After outputting the text as before, it now creates a table listing the singer's performances , completing what information is known about the composer, the work, the date of the performance, and the venue.

The «&#xa0; » characters (better known to HTML authors as a nonbreaking space, «&nbsp; » ), are used to ensure that there is something in each table cell : This gives a cleaner appearance in the browser. It would be quite possible to use the entity reference «&nbsp; » in the stylesheet so long as it was properly declared as an XML entity in a <!DOCTYPE> declaration at the start of the file.

  <xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">   <xsl:import href="soloist.xsl"/>   <xsl:template match="/">   <html><body>   <xsl:apply-templates/>   <table bgcolor="#cccccc" border="1" cellpadding="5">   <tr>   <td><b>Date</b></td>   <td><b>Venue</b></td>   <td><b>Composer</b></td>   <td><b>Work</b></td>   <td><b>Role</b></td>   </tr>   <xsl:apply-templates mode="index"/>   </table>   </body></html>   </xsl:template>   <xsl:template match="performance" mode="index">   <tr>   <td><xsl:value-of select="date"/>&#xa0;</td>   <td><xsl:value-of select="venue"/>&#xa0;</td>   <td><xsl:value-of select="composer"/>&#xa0;</td>   <td><xsl:value-of select="work"/>&#xa0;</td>   <td><xsl:value-of select="role"/>&#xa0;</td>   </tr>   </xsl:template>   </xsl:stylesheet>  

Output

Using a slightly extended version of the text in the source file, the output is as shown in Figure 5-15:

click to expand
Figure 5-15
end example
 

See Also

  • <xsl:apply-templates> on page 187

  • <xsl:apply-imports> on page 184

  • <xsl:call-template> on page 220

  • generate-id () function in Chapter 7, on page 568




XSLT 2.0 Programmer's Reference
NetBeansв„ў IDE Field Guide: Developing Desktop, Web, Enterprise, and Mobile Applications (2nd Edition)
ISBN: 764569090
EAN: 2147483647
Year: 2003
Pages: 324

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net