10. Multiple templates

The XSLT stylesheets that have been discussed so far all contained one single <template> element. In general, XSLT stylesheets contain several templates. Using multiple templates can yield a number of advantages.

- You can set up a structure in which specific tasks or specific aspects of the transformation can be regulated in different dedicated templates. This can improve the readability of the stylesheet. If an error arises somewhere it will also be much easier to locate that error and to correct it.
- The stylesheet can also become more efficient, because templates can be used several times. When a certain task needs to be executed repeatedly, you can simply invoke the template that performs this task, as often as needed.

Earlier in this tutorial, it was explained that the XSLT processor follows a certain procedure at the start of a transformation. In short, the XSLT processor firstly considers the XML elements that are available. Note that, initially the XSLT processor can only see the root node and the root element. Next, the XSLT stylesheet will be consulted to see which elements are mentioned in the match attributes of the various templates. If a match is found, the actions in that particular template will be executed. This will set the transformation in motion. Tpo initiate the transformation, there always needs to be a template which points either to the root node or to the root element.

Within a given template, it is always possible to instruct the XSLT processor to look once more for matching templates. The element that is used for this purpose is <xsl:apply-templates>. The <xsl:apply-templates> element can be used either with or without the select attribute. When <xsl:apply-templates> is used WITHOUT <select>, the XSLT parser will search for templates matching ALL the children (not only the direct children) of the elements in the context that has been set within a template. When a select attribute is included, by contrast, the XSLT processor only looks for templates matching the elements that are mentioned in "select".

The image below visualises the usage of <xsl:apply-tenmplates>.

It can be seen in this illustration that the two templates each have their own responsibility. The first template (which is shown in red) firstly serves to "start up" the transformation. This template contains a number of actions which need to be carried out in any case, such as setting up the basic structure of the HTML file. Within the HTML <body>, this template uses the <xsl:apply-templates> element. The select attribute refers to "body/letter". This first template hands the responsibility for the transformation over to another template in the stylesheet. The XSLT processor is asked to look for templates for the element <letter>. If a match is found, this templates will be executed. The transformation of the individual letters takes place in the template which is included specifically for this purpose. In the illustration above, this template is shown in green.

The first template in the example, the one that refers to the document root, will be invoked only once. The reason for this is that a valid XML document can only contain one document root and only one root node. For elements that are at a lower level in the hierarchy, the situation is different. These elements may occur many different times. The template will be invoked each time the element is found in the XML source. The template that contains the match attribute with the value "letter" is invoked for each <letter> element that is found in the XML source. If the source tree contains twelve <letter> elements, the template with attribute match="letter" will also be invoked twelve times. For this reason, the element <xsl:apply-templates> can also be used as an alternative to <xsl:for-each>!

The following stylesheet will produce the exact same result as the stylesheet that is discussed in section 6.

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="collection">
<html>
<head/>
<body>

<ul>
<xsl:apply-templates select="body/letter"/>
</ul>
</body>
</html>
</xsl:template>

<xsl:template match="letter">
<li>
<b>From <xsl:value-of select="author"/> to <xsl:value-of select="recipient"/>
</b>
<br/>
<xsl:if test="place">
<xsl:value-of select="place"/> <br/>
</xsl:if>
<xsl:if test="year">
<xsl:value-of select="year"/>
<br/>
</xsl:if>
<xsl:if test="callnumber">
<xsl:value-of select="callnumber"/>
</xsl:if>
</li>
</xsl:template>

</xsl:stylesheet>