Book HomeXML in a Nutshell

8.8. Modes

Sometimes the same input content needs to appear multiple times in the output document, formatted according to a different template each time. For instance, the titles of the chapters in a book would be formatted one way in the chapters themselves and a different way in the table of contents. Both xsl:apply-templates and xsl:template elements can have optional mode attributes that connect different template rules to different uses. A mode attribute on xsl:template element identifies in which mode that template rule should be activated. An xsl:apply-templates element with a mode attribute only activates template rules with matching mode attributes. Example 8-12 demonstrates with a stylesheet that begins the output document with a list of people's names. This is accomplished in the toc mode. Then a separate template rule, as well as a separate xsl:apply-templates element in the default mode (really no mode at all), output the complete contents of all person elements.

Example 8-12. A stylesheet that uses modes

<?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>
        <ul><xsl:apply-templates select="person" mode="toc"/></ul>
        <xsl:apply-templates select="person"/>
      </body>
    </html>
  </xsl:template>

  <!-- Table of Contents Mode Templates -->
  <xsl:template match="person" mode="toc">
    <xsl:apply-templates select="name" mode="toc"/>
  </xsl:template>

  <xsl:template match="name" mode="toc">
    <li><xsl:value-of select="last_name"/>,
    <xsl:value-of select="first_name"/></li>
  </xsl:template>

  <!-- Normal Mode Templates -->
  <xsl:template match="person">
    <p><xsl:apply-templates/></p>
  </xsl:template>

</xsl:stylesheet>

Example 8-13 shows the output when this stylesheet is applied to people.xml. The people template in Example 8-12 applies templates to its person children twice. The first time it does so in the toc mode. This selects the first person template rule in the stylesheet that outputs each person in the form <li>Turing, Alan</li>. The second time, it doesn't specify any mode. This selects the second person template rule in the stylesheet, which outputs all the character data of the person wrapped in a p element.

Example 8-13. Output from a stylesheet that uses modes to process each person twice with different templates

<html>
<head>
<title>Famous Scientists</title>
</head>
<body>
<ul>
<li>Turing,
    Alan</li>
<li>Feynman,
    Richard</li>
</ul>
<p>

      Alan
      Turing

    computer scientist
    mathematician
    cryptographer
  </p>
<p>

      Richard
      P
      Feynman

    physicist
    Playing the bongoes
  </p>
</body>
</html>

For every mode you use in the stylesheet, the XSLT processor adds one default template rule to its set of built-in rules. This applies to all element and root nodes in the specified mode and applies templates to their children in the same mode (since the usual built-in template rule for element and root nodes doesn't have a mode). For instance, the extra default rule for Example 8-10 looks like this:

<xsl:template match="*|/" mode="toc">
  <xsl:apply-templates mode="toc"/>
</xsl:template>


Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.