Templates have very specific rules. They can contain <xsl:param> elements, followed by a template body, which can contain PCDATA , XSLT instructions, extension elements, and literal result elements.
A number of XSLT elements, called instructions , may appear in a template body:
<xsl: apply-imports >
No other XSLT element may appear directly in a template body. As youll see in Chapter 9, the <xsl:param> element may appear in a template before the template body, but it is not called an XSLT instruction. In addition, other XSLT elements, such as <xsl: sort > , <xsl: otherwise > , <xsl: with-param > , can appear in templates, but only at specific locations, so W3C doesnt call them instructions. Youll see how to use each of these instructions throughout this book.
Extension elements are covered in Chapter 5; these elements are defined by the user or the XSLT processor, and extend XSLT. Many XSLT processors have defined their own extensions, and thats one of the reasons W3C has introduced the XSLT 1.1 working draft, where the extension mechanism is more regulated . Presumably, this functionality will be incorporated into XSLT 2.0.
If an element in a template body is not an XSL instruction or an extension element, then the XSLT processor must treat it as a literal result element. This means that an element must be treated literally and copied to the result tree (that is, copied to the output node tree created by the XSLT processor).
For example, in the following template body, the <TD> element is a literal result element, which will be copied to the output document:
<xsl:template match="RADIUS"> <TD>RADIUS</TD> </xsl:template>
Literal result elements may themselves have content, which is then treated as another template body and parsed by the XSLT processor. Youll see how this works later in this chapter.
Literal result elements may also have attributes, which are interpreted by the XSLT processor. For example, you can use the version attribute to specify that all XSLT elements inside a literal result element must be XSLT version 1.0 elements, as follows :
<xsl:template match="RADIUS"> <TD xsl:version="1.0">RADIUS</TD> </xsl:template>
The following list includes all the possible literal result element attributes (note that theyre all optional):
Attribute Value Templates (optional). Any XPath expressions in curly braces are evaluated, and the string value of the result is copied to an attribute in the result tree. Set to an attribute value template (see Chapter 3).
xsl:exclude-result-prefixes (optional). Specifies which namespaces are not to be copied to the result tree. Set to a whitespace-separated list of namespace prefixes.
xsl:extension-element-prefixes (optional). Makes the XSLT processor treat child elements of the literal result element in the listed namespaces as extension elements rather than literal result elements.
xsl:use-attribute-sets (optional). The attributes in the listed attribute sets are added to the literal result element and copied to the result tree. Set to a list of QNames that identify named <xsl:attribute-set> elements.
xsl:version (optional). Sets the version of XSL elements enclosed in the literal result element. Set to a number.
Now its time to put this information to work.
To indicate what node or nodes you want to work on in a template, XSLT supports various ways of matching or selecting nodes. You set the match attribute of <xsl:template> to a pattern that matches the name of the node or nodes you want to work with. Chapter 3, which is on templates, shows you how to create patterns. For example, the pattern / stands for the root node. The pattern * matches any element node. The pattern PLANET matches all <PLANET> element nodes, and so on.
To get started, Ill create a short example that replaces the root nodeand therefore the whole documentwith an HTML page. The first thing I do is create a template with the <xsl:template> element, setting the match attribute to the pattern to match /:
<?xml version="1.0"> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> . . . </xsl:template> </xsl:stylesheet>
When the root node is matched, the template is applied to that node. In this case, I want to replace the root node with an HTML document, so I just include that HTML document directly as the content of the <xsl:template> element:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns::xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <HTML> <HEAD> <TITLE> A trivial transformation </TITLE> </HEAD> <BODY> This transformation has replaced the entire document. </BODY> </HTML> </xsl:template> </xsl:stylesheet>
And thats all it takes; by using the <xsl:template> element, Ive set up a rule in the stylesheet. When the XSL processor reads the document, the first node it sees is the root node. This rule matches that root node, so the XSL processor copies the literals to the result tree that will give us the HTML doc and replace it with the HTML document, producing the following result:
<HTML> <HEAD> <TITLE> A trivial transformation </TITLE> </HEAD> <BODY> This transformation has replaced the entire document. </BODY> </HTML>
This example illustrates a first, rudimentary transformation. So far, it has created only a simple stylesheet with one <xsl:template> element, and that element contains only a literal result element. All this example has done is to replace the whole XML document with an HTML document, which is not too exciting. Next, well see how recursive processing works with the <xsl:apply-templates> element.