• Aucun résultat trouvé

Applying Templates

Chapter 5. Querying XML with XPath

6.5 XSLT Elements

6.5.3 Applying Templates

When you have a document that contains nested structures, the apply-templates element is used to recursively apply transformation rules throughout the document.

An easy example that demonstrates the concept of nested structures is formatted text, wherein paragraphs may contain sentences with bold typeface of multiple colors, code examples, or other formatting structures that may appear nested within themselves.

Another deeply nested structure is a filesystem. A directory can contain any number of files and subdirectories. Each subdirectory follows the same content rule as any other and may contain any number of files and subdirectories. The resultant tree can become quite complex.

When dealing with XML documents containing nested structures, it may be desirable to establish a set of rules (templates) for specific tags, but allow those tags and rules to be nested inside each other. You can use the apply-templates elements to accomplish this. Consider the following XML:

<deep-nest>

<title>Sample Text</title>

<big>T</big>his is an example of <red>Fancy Text</red> that comes in <blue>m<big>u</big></blue><green>l<big>

t</big></green><blue>i<big>p</big>

</blue><green>l<big>e</big></green>

colors. Many of <bold>these</bold>

elements are <big><green>N</green>

<blue>E</blue><green>S</green><blue>T</blue>

<green>E</green><blue>D</blue></big> within each other.

</deep-nest>

This XML fragment contains elements with other elements within them. There is no set order as to which tags can be embedded within others, as there is not a specified DTD. To account for this nesting in your template elements, use the xsl:apply-templates instruction. For example, the big element can occur within a color element, a bold element, or a title element. Therefore, its template element is:

<xsl:template match="big">

<font size="5"><xsl:apply-templates/></font>

</xsl:template>

Wherever there is a big element, it is replaced with the font tag. Furthermore, any content within the big tag is processed against any other template patterns since the xsl:apply-templates instruction is specified. Now let's take a look at the whole stylesheet used to process the XML:

<?xml version="1.0" encoding="iso-8859-1"?>

<xsl:stylesheet version="1.0"

xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="html"/>

<xsl:template match="deep-nest">

<html><body><xsl:apply-templates/></body></html>

</xsl:template>

<xsl:template match="title">

<h1><xsl:apply-templates/></h1>

</xsl:template>

<xsl:template match="big">

<font size="5"><xsl:apply-templates/></font>

</xsl:template>

<xsl:template match="red">

<font size="3" color="#FF0000"><u>

<xsl:apply-templates/></u></font>

</xsl:template>

<xsl:template match="blue">

<font color="#0000FF"><xsl:apply-templates/></font>

</xsl:template>

<xsl:template match="green">

<font color="#00FF00"><b><xsl:apply-templates/></b></font>

</xsl:template>

<xsl:template match="bold">

<b><i><xsl:apply-templates/></i></b>

</xsl:template>

</xsl:stylesheet>

The key to this stylesheet is well-formedness. Every XML element in the source document is accounted for in the stylesheet, and each defers to further processing by placing xsl:apply-templates square in the middle. If you run the XML and stylesheet through your XSLT processor, you get the following HTML:

<html>

<body>

<h1>Sample Text</h1>

<font size='5'>T</font>his is an example of <font color='#FF0000' size='3'>

<u>Fancy Text</u>

</font> that comes in

<font color='#0000FF'>m<font size='5'>u</font>

</font>

<font color='#00FF00'>

<b>l<font size='5'>

t</font></b>

</font>

<font color='#0000FF'>i<font size='5'>p</font>

</font>

<font color='#00FF00'>

<b>l<font size='5'>e</font></b>

</font>

colors. Many of <b><i>these</i></b>

elements are <font size='5'>

<font color='#00FF00'>

<b>N</b>

</font>

<font color='#0000FF'>E</font>

<font color='#00FF00'>

<b>S</b>

</font>

<font color='#0000FF'>T</font>

<font color='#00FF00'>

<b>E</b>

</font>

<font color='#0000FF'>D</font>

</font> within each other.

</body>

</html>