|
Master XSLT Template Processing (Continued)
For elements and the root node, the built-in template will get all child nodes and use them as input to the match-and-apply-templates routine. So in the example, the built-in template processes the document's root by telling the XSLT processor to go match and apply templates to its children. The XSLT processor now has an input set consisting of all children of the root, which, in the example, are the processing instructions and the data element. The processor now gets the first node in this set and makes that the new current node. This node is a processing instruction, which has no matching templates in our simple stylesheet so the built-in template is called, which simply ignores the processing instruction and no output is produced. The XSLT processor then gets the next node in the set and makes that the current node. This is the data element, which has a matching template. The processor executes that template and stops there. Consider applying the same stylesheet to the following modified XML document:
<?xml version="1.0"?>
<data>
Hello world!
<anotherData>
Another Hello world!
</anotherData>
</data>
What output would you expect to see? Actually the output will look identical to that obtained from the original XML document, i.e. adding the <anotherData> element has no effect on the output, here's why: After the XSLT processor finds and executes the template that matches the <data> element, it stops processing the document. Unlike the built-in template, there's nothing in our template that tells the processor to go and match templates for children of the <data> element. To do this you use the <xsl:apply-templates/> element. When the processor sees this element it'll attempt to match and apply templates for each child of the current node. Note that <data> has two children: A text node that contains "Hello world!" and an <anotherData> element. Here's a modified stylesheet with <xsl:apply-templates/> added:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/
Transform">
<xsl:template match="data">
<html>
<body>
<p><b><xsl:value-
of select="text()"/></b></p>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Applying this stylesheet to the modified example document above yields this output:
<html>
<body>
<p><b>
Hello world!
</b></p>
Hello world!
Another Hello world!
</body>
</html>
Why do we get "Hello world!" twice in the output? Because when we call <xsl:apply-templates/> the processor will attempt to find a template that matches the text child of the <data> element. When it doesn't find a matching template, it'll call the built-in template which simply copies the text to the output and hence the duplicate "Hello world!". So as you can see, understanding how the XSLT processor applies templates is key to designing your templates and their match patterns.
About the Author
Yasser Shohoud is co-founder of DevXpert, a software development and training firm based in northern Virginia. Yasser architects Web-based systems for clients, and develops and delivers DevXpert's training courses. Prior to DevXpert, Yasser was chief architect at Best Software (now Sage Software), where he led the architecture and design of its next-generation Web-based accounting software. Yasser is a contributing editor and columnist for Visual Studio Magazine. He is also a contributing editor for XML Magazine and frequent speaker at VBITS and SD. Reach Yasser at shohoudy@devxpert.com.
Back to top
|