XSL Free Tutorial

Web based School

Recursive Example


Next Next


Example 4. recursive.xml

<doc>
<para>This is a <emphasis>test</emphasis>.
<emphasis>Nested <emphasis>emphasis</emphasis></emphasis>.</para>
</doc>


Example 5. recursive.xsl

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

<xsl:template match="doc">
  <html><head><title>A Document</title></head>
  <body><xsl:apply-templates/></body></html>
</xsl:template>

<xsl:template match="para">
  <p><xsl:apply-templates/></p>
</xsl:template>

<xsl:template match="emphasis">
  <i><xsl:apply-templates/></i>
</xsl:template>

<xsl:template match="emphasis/emphasis">
  <b><xsl:apply-templates/></b>
</xsl:template>
</xsl:stylesheet>


Example 6. recursive.html

<html>
<head>
<title>A Document</title>
</head>
<body>
<p>This is a <i>test</i>.
<i>Nested <b>emphasis</b></i>.</p>
</body>
</html>


Conflict Resolution

The problem of multiple patterns that match is handled by conflict resolution:

  • Matching templates from imported modules are not considered if there is a matching template in the current module

  • Matching templates with a lower priority are not considered. The default priority is determined as follows:

    • Unqualified child or attribute names have a priority of 0.

    • Processing-instructions with a target have a priority of 0.

    • A namespace-qualified "*" child or attribute name has a priority of -0.25.

    • An unqualified "*" has a priority of -0.5

    • Any other template has a default priority of 0.5

    • Template priority may be specified explicitly with the priority attribute on <xsl:template>

  • "emphasis", "html:p", and "@foo" have a priority of 0

  • "html:*" has a priority of -0.25

  • "*" has a priority of -0.5

  • "para/emphasis" has a priority of 0.5

  • "emphasis/emphasis" has a priority of 0.5

  • "emphasis[@role]" has a priority of 0.5

It is technically an error if the conflict resolution process yields more than one template, however, XSLT processors may (silently) recover from this error by selecting the template that occurs last in the stylesheet.

Effectively, this means that stylesheet template order is the final arbiter.

Changing the Template Set

Now we have an algorithm for selecting exactly which pattern matches, but what happens if the same elements must be processed in multiple contexts? This happens, for example, when dealing with cross references, automatic tables of contents, and multiple views of the same data.

Consider the following example:

Example 7. modes.xm

<?xml version='1.0'?>
<chapter id="foo"><title>Chapter Title</title>

<para>This chapter is self-referential:
<xref linkend="foo"/>.</para>
</chapter>

And a stylesheet that produces:

Example 8. modes.html

<h2>Chapter Title</h2>

<p>This chapter is self-referential:
<i>Chapter Title</i>.</p>



The chapter title must be processed twice, once to produce the title and once to produce the cross reference.

There is no dynamic mechanism for adjusting template priority, but there is a mechanism for selecting specific sets of templates. That mechanism is called "modes".


Modes Example (Broken)

Without modes, you always get the same template:

Example 9. modes-broken.xsl

<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:template match="chapter/title">
  <h2><xsl:apply-templates/></h2>
</xsl:template>

<xsl:template match="xref">
  <xsl:variable name="linkend" select="@linkend"/>
  <xsl:apply-templates select="//*[@id=$linkend]/title"/>
</xsl:template>

<xsl:template match="para">
  <p><xsl:apply-templates/></p>
</xsl:template>

<xsl:template match="emphasis">
  <i><xsl:apply-templates/></i>
</xsl:template>

</xsl:stylesheet>



Example 10. modes-broken.html

<?xml version="1.0" encoding="utf-8"?>
<h2>Chapter Title</h2>

<p>This chapter is self-referential:
<h2>Chapter Title</h2>.</p>


Applying Style Procedurally

The other model for applying style is to select each action procedurally. A series of templates is created, such that each template explicitly selects and processes the necessary elements.

  • <xsl:for-each>

    <xsl:for-each select="row">
      <tr><xsl:apply-templates/></tr>
    </xsl:for-each>
  • Named Templates

    • <xsl:param>

      <xsl:param name="type">warning</xsl:param>
  • <xsl:call-template>

    <xsl:call-template name="admonition"/>
    • <xsl:with-param>

      <xsl:call-template name="admonition">
        <xsl:with-param name="type">caution</xsl:with-param>
      </xsl:call-template>




Next Next