| Previous | Next
Applying Templates with xsl:apply-templatesan XSLT processor reads the input XML document from top to bottom, starting at the root of the document and working its way down using preorder traversal. Template rules are activated in the order in which they match elements encountered during this traversal. This means a template rule for a parent will be activated before template rules matching the parent's children. However, one of the things a template can do is change the order of traversal. That is, it can specify which element(s) should be processed next. It can specify that an element(s) should be processed in the middle of processing another element. It can even prevent particular elements from being processed. In fact, Examples 8-4 through 8-6 all implicitly prevent the child elements of each The For example, suppose you wanted to list the names of the people in the input document; however, you want to put the last names first, regardless of the order in which they occur in the input document, and you don't want to output the professions or hobbies. First you need a name template that looks like this: <xsl:template match="name"> <xsl:value-of select="last_name"/>, <xsl:value-of select="first_name"/> </xsl:template> However, this alone isn't enough; if this were all there was in the stylesheet, not only would the output include the names, it would also include the professions and hobbies. You also need a person template rule that says to apply templates to <xsl:template match="person"> <xsl:apply-templates select="name"/> </xsl:template> Example 8-7 shows the complete stylesheet. Example 8-7. A simple XSLT stylesheet that uses xsl:apply-templates<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="name"> <xsl:value-of select="last_name"/>, <xsl:value-of select="first_name"/> </xsl:template> <xsl:template match="person"> <xsl:apply-templates select="name"/> </xsl:template> </xsl:stylesheet> When an XSLT processor applies this stylesheet to Example 8-1, this is output: <?xml version="1.0" encoding="utf-8"?> Turing, Alan Feynman, Richard The order of the template rules in the stylesheet doesn't matter. It's only the order of the elements in the input document that matters. Applying templates is also important when the child elements have templates of their own, even if you don't need to reorder the elements. For example, let's suppose you want a template rule for the root <xsl:template match="people"> <html> <head><title>Famous Scientists</title></head> <body> <xsl:apply-templates select="person"/> </body> </html> </xsl:template> This template tells the XSLT processor to replace every If you'd rather apply templates to all types of children of the Example 8-8. An XSLT stylesheet that generates a complete HTML document<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="people"> <html> <head><title>Famous Scientists</title></head> <body> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="name"> <p><xsl:value-of select="last_name"/>, <xsl:value-of select="first_name"/></p> </xsl:template> <xsl:template match="person"> <xsl:apply-templates select="name"/> </xsl:template> </xsl:stylesheet> When an XSLT processor applies this stylesheet to Example 8-1, it outputs the well-formed HTML document shown in Example 8-9. Look closely at this example, and you may spot an important change that was not explicitly caused by the instructions in the stylesheet. Example 8-9. The HTML document produced by applying Example 8-8 to Example 8-1<html> <head> <title>Famous Scientists</title> </head> <body> <p>Turing, Alan</p> <p>Feynman, Richard</p> </body> </html> The difference between Example 8-9 and all the previous output examples is that the text declaration has disappeared! Although there is an XSLT element you can use to specify whether you want a text declaration preceding your output ( |