<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
 "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
  [
    <!ENTITY selfURL   "http://www.nmt.edu/tcc/help/pubs/xslt/">
  ]
>
<article>
  <title>XSLT Reference</title>
  <articleinfo>
    <authorgroup>
      <author>
        <firstname>John W.</firstname>
        <surname>Shipman</surname>
      </author>
    </authorgroup>
    <address><email>tcc-doc@nmt.edu</email>
    </address>
    <revhistory>
      <revision>
        <revnumber>$Revision: 1.21 $</revnumber>
        <date>$Date: 2008/01/03 04:24:49 $ UT</date>
      </revision>
    </revhistory>
    <abstract>
      <para>
        Describes the XSLT language for transforming XML
        documents.
      </para>
      <para>
        This publication is available in <ulink url="&selfURL;"
        >Web form</ulink > and also as a <ulink
        url="&selfURL;xslt.pdf" >PDF document</ulink >.  Please
        forward any comments to <userinput
        >tcc-doc@nmt.edu</userinput >.
      </para>
    </abstract>
  </articleinfo>
  <section id='intro-sect'>
    <title>What is XSLT?</title>
    <para>
      XSLT is a tool for transforming an XML (eXtended Markup
      Language) document into either an HTML document, or into an
      XML document of a different document type.
    </para>
    <para>
      This document assumes that you are familiar with the
      structure of XML documents; if you are unfamiliar with XML,
      see the <ulink url='http://www.nmt.edu/tcc/help/xml/' >XML
      help page</ulink>.
    </para>
    <para>
      Many of the examples use HTML; for reference, see <ulink
      url='http://www.nmt.edu/tcc/help/pubs/xhtml/' ><citetitle
      >Building web pages with XHTML 1.1</citetitle ></ulink >.
    </para>
    <para>
      Online files related to this document:
    </para>
    <itemizedlist>
      <listitem>
        <para>
          <ulink url='&selfURL;model.xsl' ><filename
          >model.xsl</filename ></ulink >: This file is the
          skeleton of an XSLT stylesheet for converting an XML
          document to HTML.  To start a new stylesheet, make a
          copy of this file and add your title and templates.
        </para>
      </listitem>
      <listitem>
        <para>
          <ulink url='&selfURL;xslt.xml' ><filename
          >xslt.xml</filename ></ulink >: The XML DocBook source
          file for the document you are now reading.
        </para>
      </listitem>
    </itemizedlist>
  </section> <!--intro-sect-->
  <section id='example-sect'>
    <title>A brief example</title>
    <para>XSLT is not like a programming language: it is not
      sequentially executed.  Instead, an XSLT script is a
      specification of how the output looks as a function of
      input.  The basic unit is the <firstterm>template</firstterm>;
      a template usually defines how one particular type of
      XML tag is to be translated.</para>
    <para>At the Tech Computer Center, we have installed a Unix
      program called
      <userinput>xsltproc</userinput> that
      will process an XSLT script, transforming a given XML file
      into an output file in either HTML or XML.  See the
      <link linkend='xsltproc-sect'>section below on
      <userinput>xsltproc</userinput></link>.</para>
    <para>Here is a small example XML file that describes hiking
      trails inside a park:</para>
    <programlisting><![CDATA[<!DOCTYPE park SYSTEM "trails.dtd">
<park name="Lincoln Natural Forest">
  <trail dist="3400" climb="medium">Canyon Trail</trail>
  <trail climb="easy" dist="1200">Pickle Madden Trail</trail>
</park>]]></programlisting>
    <para>The root element is <sgmltag class='starttag'>park</sgmltag>.
      It contains <sgmltag class='starttag'>trail</sgmltag> elements,
      each describing one hiking trail.  We want to translate this
      to HTML that looks like this:</para>
<programlisting><![CDATA[    <html>
      <head>
        <title>Local Hiking Trails</title>
      </head>
      <body>
        <ul>
          <li>Canyon Trail: 3400 feet, climb medium</li>
          <li>Pickle Madden Trail: 1200 feet, climb easy</li>
        </ul>
      </body>
    </html>]]></programlisting>
    <para>Here is an XSLT script that does it:</para>
    <!-- For some screwball reason, you need THREE hyphens in a
     !   verbatim environment to get TWO in the output
     !-->
    <programlisting><![CDATA[<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>

<!-- This template processes the root node ("/") -->
<xsl:template match="/">
  <!-- Tags with no xsl: prefix are copied to the output -->
  <html>
    <head>
      <title>Local Hiking Trails</title> 
    </head>
    <body>
      <ul>
        <!-- Tags that start with xsl: are instructions on how
         !   to translate the document.  This one says,
         !   translate all the <trail> elements using the
         !   appropriate template (below).
         !-->
        <xsl:apply-templates select="park/trail"/>
      </ul>
    </body>
  </html>
</xsl:template>
  
<!-- This template is used to translate the <trail> elements.
 !-->
<xsl:template match="trail">
  <li> <!-- Start a new list item -->
    <!-- Output the text inside the <trail> element-->
    <xsl:value-of select="."/>
    <!-- Output a colon and a space -->
    <xsl:text>: </xsl:text>
    <!-- The next tag outputs the value of the trail element's
     !   "dist=" attribute.
     !-->
    <xsl:value-of select="@dist"/>
    <xsl:text> feet, climb </xsl:text>
    <xsl:value-of select="@climb"/>
  </li> <!-- End of the list item -->
</xsl:template>

</xsl:stylesheet>]]></programlisting>
    <para>The first line identifies the file as XML:</para>
<programlisting><![CDATA[    <?xml version="1.0"?>]]></programlisting>
    <para>The next tag identifies the file as an XSL stylesheet,
      and gives the URL of the XSLT standard:</para>
<programlisting><![CDATA[    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">]]></programlisting>
    <para>The next line is an XSLT tag stating that the output
      should be expressed in HTML and not in XML:</para>
<programlisting><![CDATA[    <xsl:output method="html"/>]]></programlisting>
    <para>The rest of the file consists of two templates.  The
      first template has the attribute <userinput>match="/"</userinput>,
      which means that the template applies to the root of the
      document.  The <userinput>"/"</userinput> part is an
      expression in the XPath language, described in the
      <link linkend="xpath-sect">XPath section</link> below,
      that selects the root of the document.</para>
    <para>The first thing inside this root template is a series
      of HTML tags like <sgmltag class="starttag">html</sgmltag>,
      <sgmltag class="starttag">head</sgmltag>, and so on.
      Because these tag names don't start with <userinput>xsl:</userinput>,
      they are copied directly to the HTML output file.  Note
      the <sgmltag class="starttag">ul</sgmltag> element that
      wraps the whole page content in a bullet list; the
      <sgmltag class="starttag">li</sgmltag> elements inside
      it will be added elsewhere.</para>
    <para>The body of the HTML page, inside the
      <sgmltag class="starttag">body</sgmltag> element, is
      created by this line:</para>
<programlisting><![CDATA[    <xsl:apply-templates select="park/trail"/>]]></programlisting>
    <para>This tag instructs the XSLT processor to go off and
      find a template that applies to the
      <sgmltag class="starttag">trail</sgmltag> elements inside
      the <sgmltag class="starttag">park</sgmltag> at the
      document's top level.  The results of applying that
      template are inserted at this point in the output file.</para>
    <para>After the remainder of the root template, we find
      the beginning of the second template.  This template
      is used to translate <sgmltag class="starttag">trail</sgmltag>
      elements:</para>
<programlisting><![CDATA[    <xsl:template match="trail">]]></programlisting>
    <para>The <userinput>match="trail"</userinput> attribute
      uses XPath to select <sgmltag class="starttag">trail</sgmltag>
      nodes.  As with the other template, the tags inside this
      template that don't start with <userinput>xsl:</userinput>
      are copied to the HTML output file.</para>
    <para>The first thing inside this template is the
      <sgmltag class="starttag">li</sgmltag> opening tag that
      will surround the content for this line and make it a
      bullet in the <sgmltag class="starttag">ul</sgmltag>
      bullet list.</para>
    <para>The next thing we want to add to the HTML page is the
      name of the trail.  In the XML input, the trail name is
      the text between the <sgmltag class="starttag">trail</sgmltag>
      and <sgmltag class="endtag">trail</sgmltag> tags.  The XPath
      expression for the content of a node is
      <userinput>"."</userinput>, and the
      <sgmltag class="starttag">xsl:value-of</sgmltag> tag
      is used to insert that content into the output file:</para>
<programlisting><![CDATA[    <xsl:value-of select="."/>]]></programlisting>
    <para>The next XSLT element outputs a colon and a space
      to the HTML page we are building:</para>
<programlisting><![CDATA[    <xsl:text>: </xsl:text>]]></programlisting>
    <para>To output the value of the <userinput>dist="..."</userinput>
      attribute, we again use
      <sgmltag class="starttag">xsl:value-of</sgmltag>.  This time
      the XPath expression selects an attribute of the context node
      (which is <sgmltag class="starttag">trail</sgmltag> inside
      this template) by using the <userinput>@</userinput>
      operator:</para>
<programlisting><![CDATA[    <xsl:value-of select="@dist"/>]]></programlisting>
    <para>This example will give you the general flavor of XSLT.
      After covering the XPath expression language used in XSLT
      (and in other XML-based tools), we'll move on to the
      actual XSLT tags.</para>
  </section> <!--example-sect-->
  <section id='namespace-sect'>
    <title>Namespaces and XSLT</title>
    <para>Since the XSLT stylesheet and the file it operates on
      are both XML documents, we need some way to distinguish
      between more than one set of XML element names.  Each
      set of names is called a <firstterm>namespace</firstterm>.</para>
    <para>The solution to this problem is to define a two-part
      element name:</para>
<programlisting>    &lt;<replaceable>namespace</replaceable
>:<replaceable>element-name</replaceable
>...&gt;</programlisting>
<para>where <replaceable>namespace</replaceable> defines
which set of element names we're talking about, and
<replaceable>element-name</replaceable> is the element name
inside that namespace.</para>
<para>In an XSLT stylesheet, any element name that doesn't
have an <userinput>xsl:</userinput> prefix
represents an element (with its content, if any) that gets
written to the output.</para>
<para>Besides the <userinput>xsl:</userinput>
namespace and the namespace of the elements you are writing
to the output, you may also use other namespaces.  You can
control which namespaces are output and which are acted on:
see the section on the <link
linkend="root-elt-attrs">attributes of the root
element</link>, below.</para>
<para>For an example of a situation where you need to refer
to other namespaces, see the section on
<link linkend="extension-elts">extension elements</link>
below.</para>
<para>For more information, see the <ulink
url="http://www.w3.org/TR/1999/REC-xml-names-19990114/">reference
for XML namespaces</ulink>.</para>
</section> <!--namespace-sect-->
<section id='xpath-sect'>
  <title>XPath reference</title>
  <para>The XPath language is used to describe locations in a document
  tree.  It is the expression language used by XSLT.  See the
  <ulink url="http://www.w3.org/TR/xpath">XPath
  specification</ulink> for complete details.</para>
  <para>A well-formed XML document can be visualized as a tree
  (in the computer science meaning of the term),
  and this view is used throughout XPath and XSLT.  For example,
  if a certain document represents a book, it might have
  a top-level tag
  <sgmltag class="starttag">book</sgmltag>, containing elements like
  <sgmltag class="starttag">chapter</sgmltag> and
  <sgmltag class="starttag">appendix</sgmltag>.</para>
  <para>A few important definitions:</para>
  <itemizedlist>
    <listitem>
      <para>A <firstterm>node</firstterm> is the basic building block
      of the document tree, that is, the data structure used to
      represent an XML document during its processing by an XSLT
      script.</para>
    </listitem>
    <listitem>
      <para>The node representing the outermost tag of the document
      is called the <firstterm>root node</firstterm> of the tree.</para>
    </listitem>
    <listitem>
      <para>All nodes except the root node of the tree have a
      <firstterm>parent node</firstterm>, and many nodes can
      have <firstterm>child nodes</firstterm> under them.</para>
      <para>To continue the example above, the
      <sgmltag class="starttag">book</sgmltag> node is the root,
      and its children are the
      <sgmltag class="starttag">chapter</sgmltag> and
      <sgmltag class="starttag">appendix</sgmltag> elements.</para>
    </listitem>
    <listitem id='context-node'>
      <para>All XPath expressions are evaluated in the context of
      a particular node (location) in the document.  That node is
      called the <firstterm>context node</firstterm>.</para>
    </listitem>
    <listitem id='context-size'>
      <para>The <firstterm>context size</firstterm> is the number
      of children of the context node's parent.  For example, if
      the context node is one of seven children of its parent,
      the context size is seven.</para>
    </listitem>
    <listitem id='context-pos'>
      <para>The <firstterm>context position</firstterm> is the
      child number of the context node relative to its parent.
      For example, if the context node is the third of seven
      children of its parent, its context position is three.</para>
    </listitem>
  </itemizedlist>
  <section id='data-types-sect'>
    <title>Data types in XPath</title>
    <para>XPath expressions use these data types:</para>
    <variablelist>
      <varlistentry>
        <term><userinput>node-set</userinput></term>
        <listitem>
          <para>Many XPath operations select a set of zero or
          more nodes.  For example, the expression
          <userinput>"address"</userinput> selects all of the
          <sgmltag class="starttag">address</sgmltag> elements
          that are children of the context node.  This node-set
        may contain no nodes, one node, or many.</para></listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>boolean</userinput></term>
        <listitem>
        <para>A true or false value.</para></listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>number</userinput></term>
        <listitem>
          <para>Numbers in XPath are represented using floating point.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>string</userinput></term>
        <listitem>
          <para>A string of characters.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section> <!--data-types-sect-->
  <section id='node-type-sect'>
    <title>Node types</title>
    <para>These types of nodes are used to represent a document as a
    tree:</para>
    <itemizedlist>
      <listitem>
        <para>A <firstterm>document</firstterm> node roots the tree.
        It will always have as its child an element node for
        the outermost element of the document.  It may also have
        comment or processing instruction nodes as children, if
      those nodes appear outside the document.</para></listitem>
      <listitem>
        <para>Each <firstterm>element node</firstterm> represents
      one XML tag and its children, if any.</para></listitem>
      <listitem>
        <para><firstterm>Attribute nodes</firstterm> represent
        attributes of an element.  Such nodes have element nodes
        as a parent, but are not considered ordinary children of
      the parent element.</para></listitem>
      <listitem>
        <para>Chunks of text inside an element become
      <firstterm>text nodes</firstterm>.</para></listitem>
      <listitem>
        <para>Comments in the document are represented as
      <firstterm>comment nodes</firstterm>.</para></listitem>
      <listitem>
        <para><firstterm>Processing instructions</firstterm> come from
        XML's <userinput>&lt;?...?&gt;</userinput> construct.</para>
      </listitem>
    </itemizedlist>
  </section> <!--node-type-sect-->
  <section id='node-test-sect'>
    <title>Node tests</title>
    <para>Most XPath expressions are used to select zero or more
    nodes from the document.  For example, the XPath expression
    <userinput>cue</userinput> selects all
    <sgmltag class="starttag">cue</sgmltag> child elements of
    the context node.</para>
    <para>These functions are used to select certain special
    node sets:</para>
    <variablelist>
      <varlistentry>
        <term><userinput>text()</userinput></term>
        <listitem>
          <simpara>This function selects all the text
          children of the context node.</simpara>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>comment()</userinput></term>
        <listitem>
          <simpara>Selects all comments that are children of
          the context node.</simpara>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>processing-instruction()</userinput></term>
        <listitem>
          <simpara>Selects all children of the context node
          that are processing instructions.</simpara>
        </listitem>
      </varlistentry>
    </variablelist>
  </section> <!--node-test-sect-->
  <section id='axis-sect'>
    <title>Axis selection in XPath</title>
    <para>XPath expressions can select nodes using a number
    of different <firstterm>axis</firstterm> specifiers.
    Each axis describes a different set of nodes relative
    to the context node, a different direction.  For example, using the
    <userinput>child</userinput> axis
    allows you to select only nodes that are children
    of the context node.  The <userinput>child</userinput>
    axis is the default axis.</para>
    <para>To select nodes from a specific axis, use the syntax
    <userinput><replaceable>axis</replaceable
    >::<replaceable>e</replaceable></userinput> where
    <replaceable>e</replaceable> is any XPath expression.
    For example, <userinput>ancestor::cluster</userinput>
    would select all <sgmltag class="starttag">cluster</sgmltag>
    elements that are ancestors of the context node.</para>
    <para>Here are the axis specifiers:</para> 
    <variablelist>
      <varlistentry>
        <term><userinput>child::</userinput></term>
        <listitem>
          <para>Selects children of the context node.  Attribute
          nodes are not included; use the
          <userinput>attribute::</userinput>
          axis to get attribute nodes.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>parent::</userinput></term>
        <listitem>
          <para>
            Selects only the parent node, if there is one.  Can
            be abbreviated as &#x201c;<userinput
            >../</userinput >&#x201d;
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>self::</userinput></term>
        <listitem>
          <para>
            Selects only the context node.  This can be
            abbreviated as &#x201c;<userinput >./</userinput
            >&#x201d;.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>attribute::</userinput></term>
        <listitem>
          <para>
            Selects only the attributes of the context node.
            Can be abbreviated as &#x201c;<userinput
            >@</userinput >&#x201d;.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>ancestor::</userinput></term>
        <listitem>
          <para>Refers to all ancestors of the context node: its
          parent, its parent's parent, and so on up to and
          including the document node.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>ancestor-or-self::</userinput></term>
        <listitem>
          <para>Refers to the context node and its ancestors.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>descendant::</userinput></term>
        <listitem>
          <para>Refers to the descendants of the context node:
          its children, their children, and so on up to 
          and including the leaves of the tree.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>descendant-or-self::</userinput></term>
        <listitem>
          <para>Refers to the context node and its descendants.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>preceding-sibling::</userinput></term>
        <listitem>
          <para>Refers to all children of the context node's parent
          that occur before the context node.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>following-sibling::</userinput></term>
        <listitem>
          <para>Refers to all children of the context node's parent
          that occur after the context node.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>preceding::</userinput></term>
        <listitem>
          <para>All nodes that precede the context node in the whole
          document.  This set does not include the context node's
          descendants or attributes.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>following::</userinput></term>
        <listitem>
          <para>All nodes that follow the context node in the whole
          document.  This set does not include the context node's
          descendants or attributes.</para>
        </listitem>
      </varlistentry>
    </variablelist>
    <informalfigure>
      <!-- <title>Axis specifiers in XSLT</title> -->
      <mediaobject>
        <imageobject role="html">
          <!-- The source file for this image is the xfig file axes.fig,
               !   exported at 100% magnification to axes.jpg.
               !-->
          <imagedata fileref="axes.jpg"></imagedata>
        </imageobject>
        <imageobject role="fo">
          <!-- The source file for this image is the xfig file axes.fig,
               !   exported at 100% magnification to axes.pdf.
               !-->
          <imagedata scale="75" fileref="axes.pdf"></imagedata>
        </imageobject>
      </mediaobject>
    </informalfigure>
  </section> <!--axis-sect-->
  <section id='operator-sect'>
    <title>XPath operators</title>
    <para>Here are the operators used in XPath expressions.  In
    the table below, <replaceable>e</replaceable> stands for
    any XPath expression.</para>
    <informaltable>
      <tgroup cols="2">
        <colspec colwidth="1*"></colspec>
        <colspec colwidth="4*"></colspec>
        <tbody>
          <row>
            <entry><userinput><replaceable>e1</replaceable
            >+<replaceable>e2</replaceable></userinput></entry>
            <entry>If <replaceable>e1</replaceable> and
            <replaceable>e2</replaceable> are numbers, their sum.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable
            >-<replaceable>e2</replaceable></userinput></entry>
            <entry><replaceable>e1</replaceable> minus
            <replaceable>e2</replaceable>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable
            >*<replaceable>e2</replaceable></userinput></entry>
            <entry>The product of <replaceable>e1</replaceable>
            and <replaceable>e2</replaceable>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> div
            <replaceable>e2</replaceable></userinput></entry>
            <entry>If <replaceable>e1</replaceable> and
            <replaceable>e2</replaceable> are numbers, their
            quotient as a floating-point value.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> mod
            <replaceable>e2</replaceable></userinput></entry>
            <entry>The floating-point remainder of
            <replaceable>e1</replaceable> divided by
            <replaceable>e2</replaceable>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> =
            <replaceable>e2</replaceable></userinput></entry>
            <entry>Tests to see if <replaceable>e1</replaceable>
            equals <replaceable>e2</replaceable>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> &amp;lt;
            <replaceable>e2</replaceable></userinput></entry>
            <entry>Tests to see if <replaceable>e1</replaceable>
            is less than <replaceable>e2</replaceable>.  You
            can't say <userinput
            ><replaceable>e1</replaceable> &lt;
            <replaceable>e2</replaceable></userinput>
            inside an attribute: the less-than sign must be escaped as
            <userinput>"&amp;lt;"</userinput>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> &amp;lt;=
            <replaceable>e2</replaceable></userinput></entry>
            <entry>Tests to see if <replaceable>e1</replaceable>
            is less than or equal to
            <replaceable>e2</replaceable>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> &amp;gt;
            <replaceable>e2</replaceable></userinput></entry>
            <entry>Tests for greater-than.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> &amp;gt;=
            <replaceable>e2</replaceable></userinput></entry>
            <entry>Tests for greater or equal.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> !=
            <replaceable>e2</replaceable></userinput></entry>
            <entry>Tests for inequality.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> and
            <replaceable>e2</replaceable></userinput></entry>
            <entry>True if both <replaceable>e1</replaceable>
            and <replaceable>e2</replaceable> are true.
            If <replaceable>e1</replaceable> is false,
            <replaceable>e2</replaceable> is not evaluated.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable> or
            <replaceable>e2</replaceable></userinput></entry>
            <entry>True if either <replaceable>e1</replaceable>
            or <replaceable>e2</replaceable> is true.
            If <replaceable>e1</replaceable> is true,
            <replaceable>e2</replaceable> is not evaluated.</entry>
          </row>
          <row>
            <entry><userinput>/<replaceable>e</replaceable></userinput>
            </entry>
            <entry>Evaluate <replaceable>e</replaceable> starting
            at the document node.  For example,
            <userinput>"/barge"</userinput> selects the
            <sgmltag class="starttag">barge</sgmltag>
            element that is the child of the document node.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable
            >/<replaceable>e2</replaceable></userinput></entry>
            <entry>The <userinput>/</userinput>
            operator separates levels in a tree.  For example,
            <userinput>"/barge/load"</userinput>
            selects all <sgmltag class="starttag">load</sgmltag>
            children of
            the <sgmltag class="starttag">barge</sgmltag>
            element child of the document node.</entry>
          </row>
          <row>
            <entry><userinput>//<replaceable>e</replaceable>
            </userinput></entry>
            <entry>Abbreviation for
            <userinput>descendant-or-self::<replaceable
            >e</replaceable></userinput>.</entry>
          </row>
          <row>
            <entry><userinput>./<replaceable>e</replaceable>
            </userinput></entry>
            <entry>Abbreviation for <userinput
            >self::<replaceable>e</replaceable></userinput>.</entry>
          </row>
          <row>
            <entry><userinput>../<replaceable>e</replaceable
            ></userinput></entry>
            <entry>Abbreviation for
            <userinput>parent::<replaceable
            >e</replaceable></userinput>.</entry>
          </row>
          <row>
            <entry><userinput>@<replaceable>e</replaceable
            ></userinput></entry>
            <entry>Abbreviation for
            <userinput>attribute::<replaceable>e</replaceable
            ></userinput>.</entry>
          </row>
          <row>
            <entry><userinput><replaceable>e1</replaceable
            >|<replaceable>e2</replaceable></userinput></entry>
            <entry>Selects the union of nodes that match
            <replaceable>e1</replaceable> and those that match
            <replaceable>e2</replaceable>.</entry>
          </row>
          <row>
            <entry><userinput>*</userinput></entry>
            <entry>A wild-card operator; matches all nodes of
            the proper type for the context.  For example,
            <userinput>"*"</userinput> selects all child elements
            of the context node, and
            <userinput>"feet/@*"</userinput> selects all attributes
            of the context node's
            <sgmltag class="starttag">feet</sgmltag> children.</entry>
          </row>
          <row>
            <entry id='xpath-predicate'>
              <userinput><replaceable>e1</replaceable
              >[<replaceable>e2</replaceable>]</userinput></entry>
              <entry><para>Square brackets enclose a
              <firstterm>predicate</firstterm>, which specifies an
              expression <replaceable>e2</replaceable>
              that selects nodes from a larger set
              <replaceable>e1</replaceable>.For example,
              in the XPath expression
              <userinput>"para[@class='note']"</userinput>,
              the <userinput>para</userinput> selects all
              <sgmltag class="starttag">para</sgmltag> children
              of the context node, and then the predicate selects
              only the children that have an attribute
              <userinput>class="note"</userinput>.
              Another example:
              <userinput>"item[1]"</userinput> would select
              the first <sgmltag class="starttag">item</sgmltag>
              child of the context node.</para></entry>
          </row>
          <row>
            <entry><userinput>$<replaceable>e</replaceable>
            </userinput></entry>
            <entry>The dollar sign indicates that the following
            name is a variable name.  For example, in an XSLT
            script, if variable n is set to 357,
            <sgmltag class="starttag"
                     >xsl:value-of select="$n"/</sgmltag> is expanded
            to the string <userinput>"357"</userinput>.</entry>
          </row>
        </tbody>
      </tgroup>
    </informaltable>
    <para>Here is a table showing the precedence of the XPath
    operators, from highest to lowest:</para>
    <itemizedlist>
      <listitem>
      <para><userinput>() $</userinput></para></listitem>
      <listitem>
        <para><userinput><replaceable>e<subscript>1</subscript
        ></replaceable>[<replaceable>e<subscript>2</subscript
        ></replaceable>]</userinput></para></listitem>
        <listitem>
        <para><userinput>::</userinput></para></listitem>
        <listitem>
        <para><userinput>. ..</userinput></para></listitem>
        <listitem>
        <para><userinput>/ //</userinput></para></listitem>
        <listitem>
        <para><userinput>|</userinput></para></listitem>
        <listitem>
        <para>Unary <userinput>-</userinput></para></listitem>
        <listitem>
        <para><userinput>* div mod</userinput></para></listitem>
        <listitem>
        <para><userinput>+ -</userinput></para></listitem>
        <listitem>
        <para><userinput>&lt; &lt;= &gt;= &gt;</userinput></para></listitem>
        <listitem>
        <para><userinput>= !=</userinput></para></listitem>
        <listitem>
        <para><userinput>and</userinput></para></listitem>
        <listitem>
        <para><userinput>or</userinput></para></listitem>
    </itemizedlist>
  </section> <!--operator-sect-->
  <section id='xpath-functions-sect'>
    <title>XPath functions</title>
    <para>XPath supplies these functions:</para>
    <variablelist>
      <varlistentry id='boolean-func'>
        <term><userinput>boolean(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Converts object <replaceable>e</replaceable> to
          Boolean type.  False values include numeric zero,
          empty strings, and empty node sets; other values
        are considered true.</para></listitem>
      </varlistentry>
      <varlistentry id='ceiling-func'>
        <term><userinput>ceiling(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns the integer closest to infinity
          that is less than or equal to <replaceable>e</replaceable>.
          Examples:
          <userinput>ceiling(5.9)</userinput> returns
          <userinput>6</userinput>;
          <userinput>ceiling(-5.9)</userinput> returns
          <userinput>-5</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='concat-func'>
        <term><userinput>concat(<replaceable>e1</replaceable>,
        <replaceable>e2</replaceable>, ...)</userinput></term>
        <listitem>
          <para>Concatenates the string values of its arguments
          and returns the result as a single string.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='contains-func'>
        <term><userinput>contains(<replaceable>s1</replaceable>,
        <replaceable>s2</replaceable>)</userinput></term>
        <listitem>
          <para>True if string <replaceable>s1</replaceable>
          contains <replaceable>s2</replaceable>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='count-func'>
        <term><userinput>count(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>For a node-set <replaceable>e</replaceable>,
          returns the number of nodes in that set.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='false-func'>
        <term><userinput>false()</userinput></term>
        <listitem>
          <para>Returns the Boolean &#x201c;false&#x201d; value.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='floor-func'>
        <term><userinput>floor(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns the integer closest to minus infinity
          that is greater than or equal to
          <replaceable>e</replaceable>. Examples:
          <userinput>floor(5.9)</userinput> returns
          <userinput>5</userinput>;
          <userinput>floor(-5.9)</userinput> returns
          <userinput>-6</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='id-func'>
        <term><userinput>id(<replaceable>e</replaceable>)</userinput></term>
        <listitem>
          <para>For a string <replaceable>e</replaceable>,
          this function returns a node-set containing the
          element whose <userinput>id</userinput>
          attribute matches <replaceable>e</replaceable>, if
          there is one.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='lang-func'>
        <term><userinput>lang(<replaceable>s</replaceable
        >)</userinput></term>
        <listitem>
          <para>This function tests whether a language code
          <replaceable>s</replaceable> is a substring of the
          context node's language attribute
          (from the <userinput>xml:lang</userinput> attribute).
          For example, <userinput>lang("en")</userinput>
          would return a true value if the context node has
          an attribute <userinput>xml:lang="en-us"</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='last-func'>
        <term><userinput>last()</userinput></term>
        <listitem>
          <para>Returns the context size; see the section above on
          <link linkend="context-size">context size.</link></para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>local-name(<replaceable>n</replaceable
        >)</userinput></term>
        <listitem>
          <para>For a node set <userinput><replaceable
          >n</replaceable></userinput>, this function returns
          the local name of the first element, that is, the
          element name without any namespace.  If the argument
          is omitted, returns the local name of the
          <link linkend="context-node">context node</link>.</para>
          <para>For example, if the context node is an
          <userinput>xsl:message</userinput>
          element, <userinput>local-name()</userinput>
          will return the string <userinput
          >"message"</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='normalize-space-func'>
        <term><userinput>normalize-space(<replaceable>s</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns the string <replaceable>s</replaceable>,
          except that all leading and trailing whitespace are
          removed, and all internal clumps of whitespace are
          replaced by single spaces.</para>
          <para>If the argument is omitted, it operates on the string value
          of the current node.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='not-function'>
        <term><userinput>not(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns the Boolean complement of the truth value
          of expression <replaceable>e</replaceable>: true if
          <replaceable>e</replaceable> is false, false if it
          is true.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='number-func'>
        <term><userinput>number(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Converts an expression <replaceable>e</replaceable>
          to a number.  If <replaceable>e</replaceable> is not
          a valid number, you get the special numeric value
          <userinput>NaN</userinput> (not a
          number).  If <replaceable>e</replaceable> is a Boolean
          value, you get 1 for true and 0 for false.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='position-func'>
        <term><userinput>position()</userinput></term>
        <listitem>
          <para>Returns the context position; see
          <link linkend="context-pos">context position</link>,
        above.</para></listitem>
      </varlistentry>
      <varlistentry id='round-func'>
        <term><userinput>round(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns the integer closest to the value of
          expression <replaceable>e</replaceable>.
          Values with a fractional part of 0.5 are rounded
          towards infinity.
          Examples:
          <userinput>round(5.1)</userinput> returns
          <userinput>5</userinput>;
          <userinput>round(5.5)</userinput> returns
          <userinput>6</userinput>; and
          <userinput>round(-5.5)</userinput> returns
          <userinput>-5</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='starts-with-func'>
        <term><userinput>starts-with(<replaceable>s1</replaceable>,
        <replaceable>s2</replaceable>)</userinput></term>
        <listitem>
          <para>True if string <replaceable>s1</replaceable>
          starts with string <replaceable>s2</replaceable>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='string-func'>
        <term><userinput>string(<replaceable>e</replaceable
        >)</userinput></term>
        <listitem>
          <para>Converts <replaceable>e</replaceable> to a string.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='string-length-func'>
        <term><userinput>string-length(<replaceable>s</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns the length of string
          <replaceable>s</replaceable>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='substring-func'>
        <term><userinput>substring(<replaceable>s</replaceable>,
        <replaceable>n1</replaceable>, <replaceable>n2</replaceable
        >)</userinput></term>
        <listitem>
          <para>Returns a substring of <replaceable>s</replaceable>
          starting at position <replaceable>n1</replaceable>
          (counting from 1), and ending <replaceable>n2</replaceable>
          characters later, or at the end of the string, whichever
          comes first.  You can omit the third argument, and it
          will return the substring starting at position
          <replaceable>n1</replaceable> and going through the
          end of <replaceable>s</replaceable>.  For example,
          <userinput>"substring('abcdefgh', 3, 4)"</userinput>
          returns <userinput>"cdef"</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='substring-after-func'>
        <term><userinput>substring-after(<replaceable>s1</replaceable>,
        <replaceable>s2</replaceable>)</userinput></term>
        <listitem>
          <para>If <replaceable>s2</replaceable> is a substring
          of <replaceable>s1</replaceable>, returns the part
          of <replaceable>s1</replaceable> after the first
          occurrence of <replaceable>s2</replaceable>; otherwise
          it returns the empty string.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='substring-before-func'>
        <term><userinput>substring-before(<replaceable>s1</replaceable>,
        <replaceable>s2</replaceable>)</userinput></term>
        <listitem>
          <para>If <replaceable>s2</replaceable> is a substring
          of <replaceable>s1</replaceable>, returns the part
          of <replaceable>s1</replaceable> before the first
          occurrence of <replaceable>s2</replaceable>; otherwise
          it returns the empty string.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='sum-func'>
        <term><userinput>sum(<replaceable>n</replaceable
        >)</userinput></term>
        <listitem>
          <para>For a node-set <replaceable>n</replaceable>,
          this function converts each node to a number,
          then returns the sum of those numbers.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='translate-func'>
        <term><userinput>translate(<replaceable>s1</replaceable>,
        <replaceable>s2</replaceable>,
        <replaceable>s3</replaceable>)</userinput></term>
        <listitem>
          <para>The result is a copy of string
          <replaceable>s1</replaceable> with each
          occurrence of a character from string
          <replaceable>s2</replaceable> replaced with the
          corresponding character from string
          <replaceable>s3</replaceable>.</para>
          <para>If <replaceable>s3</replaceable> is shorter than
          <replaceable>s2</replaceable>, this function will delete
          from its result any characters 
          from <replaceable>s2</replaceable> that don't
          correspond to characters in
          <replaceable>s3</replaceable>.</para>
        </listitem>
      </varlistentry>
      <varlistentry id='true-func'>
        <term><userinput>true()</userinput></term>
        <listitem>
          <para>Returns the Boolean &#x201c;true&#x201d; value.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section> <!--xpath-functions-sect-->
</section> <!--xpath-sect-->
<section id='overall-sect'>
  <title>Overall XSLT stylesheet structure</title>
  <para>Here is the overall structure of an XSLT stylesheet:</para>
  <programlisting
>&lt;xsl:stylesheet ...&gt;
  <replaceable>top-level-only elements</replaceable>
  <replaceable>templates</replaceable>
&lt;/xsl:stylesheet&gt;</programlisting>
  <para>The root element must be either <sgmltag
  class="starttag">xsl:stylesheet</sgmltag> or <sgmltag
  class="starttag">xsl:transform</sgmltag>; they are equivalent.</para>
  <para>There are certain elements called
  <firstterm>top-level-only elements</firstterm> that must
  be just inside the root element.  These are discussed
  below in the section on <link
  linkend="top-level-elts">top-level elements.</link></para>
  <para>The rest of the stylesheet consists of any mixture
  of these elements:</para>
  <itemizedlist>
    <listitem>
      <para><link linkend="template-elts">Basic template
      elements</link> are for defining templates and
    creating modular pieces of templates.</para></listitem>
    <listitem>
      <para><link linkend="output-elts">Output elements</link>
    are used to write things to the output.</para></listitem>
    <listitem>
      <para>There are several <link
      linkend="branching-elts">branching elements</link> that
    provide iteration and optional content.</para></listitem>
    <listitem>
      <para>See the section on
      <link linkend="advanced-elts">advanced elements</link>
    for additional useful features.</para></listitem>
  </itemizedlist>
</section> <!--overall-sect-->
<section id='root-elts'>
  <title>The root element <sgmltag
  class="starttag">xsl:stylesheet</sgmltag></title>
  <para>The root element of any XSLT stylesheet must be
  <sgmltag class="starttag">xsl:stylesheet</sgmltag>.
  This tag is described below, followed by the &#x201c;top level
  tags&#x201d; that must be children of
  <sgmltag class="starttag">xsl:stylesheet</sgmltag>,
  that is, they must be outside all
  <sgmltag class="starttag">xsl:template</sgmltag> elements.</para>
  <section id='root-elt-attrs'>
    <title><sgmltag class="starttag">xsl:stylesheet</sgmltag>
    attributes</title>
    <para>Attributes of <sgmltag
    class="starttag">xsl:stylesheet</sgmltag> include:</para>
    <variablelist>
      <varlistentry>
        <term><userinput>version</userinput> (required)</term>
        <listitem>
          <para>Use <userinput
          >version="1.0"</userinput>.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>xmlns:xsl</userinput></term>
        <listitem>
          <para>Use <userinput
          >xmlns:xsl="http://www.w3.org/1999/XSL/Transform"</userinput>
          to connect your document to this version of the XSLT
          standard.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>extension-element-prefixes</userinput></term>
        <listitem>
          <para>This attribute defines a prefix you will use to
          invoke extension elements.  See
          <link linkend="extension-elts">extension
          elements</link> below.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>exclude-result-prefixes</userinput></term>
        <listitem>
          <para>Normally, any element whose name doesn't start
          with <userinput>xsl:</userinput>
          is copied to the output.  However, if you are using
          extension elements, you can use this attribute to
          specify that elements with certain prefixes are
          to be processed and not copied to the output.  See
          the section on <link linkend="extension-elts">extension
          elements</link> below for an example.</para>
        </listitem>
      </varlistentry>
    </variablelist>
  </section> <!--root-elt-attrs-->
</section> <!--root-elts-->
<section id='top-level-elts'>
  <title>Top-level elements</title>
  <para>The elements described in this section can appear only
  as children of the root <sgmltag
  class="starttag">xsl:stylesheet</sgmltag> element.  They
  specify options that affect the entire translation of the
  input file to the output.</para>
  <section id='xsl-output'>
    <title><sgmltag class="starttag">xsl:output</sgmltag>:
    Select output options</title>
    <para>This optional tag defines what tag format to use in
    the output file.  The default is XML format.  This tag
    must be a child of the root
    <sgmltag class="starttag">xsl:stylesheet</sgmltag> element.</para>
    <para>Attributes include:</para>
    <variablelist>
      <varlistentry>
        <term><userinput>method</userinput></term>
        <listitem>
          <para>Values include <userinput>xml</userinput> for XML
          output; <userinput>html</userinput> for output as HTML;
          and <userinput>text</userinput> if the output is just
          ordinary text, not tagged.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>version</userinput></term>
        <listitem>
          <para>Identifies the version of the output method.</para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><userinput>omit-xml-declaration</userinput></term>
        <listitem>
          <para>
            If the output method is XML, a
            <userinput>&lt;?xml...?&gt;</userinput> processing
            instruction is written to the output file unless
            you specify
            <userinput>omit-xml-declaration="yes"</userinput>.
            The default is <userinput>"no"</userinput>.  No XML
            declaration is written for the other output
            methods.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <userinput>indent</userinput>
        </term>
        <listitem>
          <para>
            Use <userinput>indent="yes"</userinput> to request
            that XML or HTMl output be indented.  Some XSLT
            processors may not support this option.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <userinput>encoding</userinput>
        </term>
        <listitem>
          <para>
            Specifies the character encoding that will appear
            in the XML processing instruction, if one is
            generated.  Examples:
            <userinput>ISO-8859-1</userinput>,
            <userinput>UTF-8</userinput>.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <userinput>doctype-system</userinput>
        </term>
        <listitem>
          <para>
            Use this attribute to add a
            <userinput>&lt;!DOCTYPE&gt;</userinput> declaration
            to generated HTML or XML.
          </para>
          <para>
            If you want to generate a
            <userinput>SYSTEM</userinput> document type, set
            this attribute to the URI containing the DTD.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term>
          <userinput>doctype-public</userinput>
        </term>
        <listitem>
          <para>
            If you want to generate a
            <userinput>&lt;!DOCTYPE&gt;</userinput> declaration
            using a public identifier, set this attribute to
            the public identifier and also set the
            <userinput>doctype-system</userinput> attribute to
            the URI corresponding to that public identifier.
          </para>
        </listitem>
      </varlistentry>
    </variablelist>
    <para>
      Here is an example of an <sgmltag
      class="starttag">xsl:output</sgmltag> element for
      generating strict XHTML 1.0:
    </para>
    <programlisting
        >&lt;xsl:output method="xml" encoding="ISO-8859-1" indent="yes"
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"/&gt;</programlisting>
      <para>
        The file generated with these output options will start
        like this:
      </para>
      <programlisting
>&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;</programlisting>
    </section> <!--xsl-output-->
    <section id='preserve-space'>
      <title><sgmltag
        class="starttag">xsl:preserve-space</sgmltag>: Preserving
          white space</title>
      <para>Use this element to specify for which input elements
        white space is preserved.  Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>elements</userinput> (required)</term>
          <listitem>
            <para>A list of element names separated by spaces.</para>
          </listitem>
        </varlistentry>
      </variablelist>
            <para>For example, this element would cause white
              space to be preserved in <sgmltag
            class="starttag">remark</sgmltag> and <sgmltag
            class="starttag">warning</sgmltag> elements:</para>
<programlisting><![CDATA[    <xsl:preserve-space elements="remark warning"/>]]></programlisting>
    </section> <!--preserve-space-->
    <section id='strip-space'>
      <title><sgmltag
        class="starttag">xsl:strip-space</sgmltag>: Removing
          non-significant white space</title>
      <para>By &#x201c;non-significant white space,&#x201d; we mean white
        space that occurs between elements.  White space that
        occurs inside text content is considered significant.
        This tag specifies for which elements non-significant
        white space is discarded.  Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>elements</userinput> (required)</term>
          <listitem>
            <para>A list of element names separated by spaces.</para>
            <para>For example, this element would cause white
              space to be deleted in <sgmltag
            class="starttag">rant</sgmltag> elements:</para>
<programlisting><![CDATA[    <xsl:strip-space elements="rant"/>]]></programlisting>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--strip-space-->
    <section id='xsl-import'>
      <title><sgmltag class="starttag">xsl:import</sgmltag>: Use
        templates from another stylesheet</title>
      <para>The purpose of this tag is to allow modularity in
        the design of stylesheets.  After using the <sgmltag
        class="starttag">xsl:import</sgmltag> element to refers to
        another XSLT stylesheet, you can use any of the templates
        in that other stylesheet.</para>
      <para>When your stylesheet and the other stylesheet have
        templates for the same situation, your stylesheet takes
        precedence.  Every template is assigned a
        <firstterm>priority</firstterm>, and the priority of an
        imported stylesheet is lower than that of the importing
        stylesheet.</para>
      <para>Even in the case that some template
        <replaceable>T1</replaceable> from your stylesheet
        overrides another template <replaceable>T2</replaceable>
        from an imported stylesheet, template
        <replaceable>T1</replaceable> can use
        <replaceable>T2</replaceable> in its processing.  See the
        <link linkend="xsl-apply-imports"><sgmltag
        class="starttag">xsl:apply-imports</sgmltag></link> tag,
        below.</para>
      <para>Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>href</userinput> (required)</term>
          <listitem>
            <para>This attribute defines the URI of the
              stylesheet you are importing.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>Example (note that this tag is always empty):</para>
<programlisting><![CDATA[    <xsl:import href="http://www.nmt.edu/tcc/help/xml/"/>]]></programlisting>
    </section> <!--xsl-import-->
    <section id='xsl-key'>
      <title><sgmltag class="starttag">xsl:key</sgmltag>: Create
        an index to optimize input document access</title>
      <para>The purpose of the <sgmltag class="starttag">xsl:key</sgmltag>
        element is to define an <firstterm>index</firstterm>
        on information in the input file, so that the XSLT processor
        can retrieve that information more efficiently than by
        searching the entire file.  This is admittedly an
        advanced feature, but can be very useful for larger projects.</para>
      <para>You must give each key a name, using the <userinput
       >name</userinput> attribute, that will be
        used to refer to it later.  Two more attributes describe
        which nodes to index, and what text to use as the index:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>match</userinput></term>
          <listitem>
            <para>To define which nodes of the input document are
              indexed, use attribute <userinput
             >match="<replaceable>m</replaceable>"</userinput>,
              where <replaceable>m</replaceable> is an <link
              linkend="xpath-sect">XPath</link> expression
              describing a node set.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>use</userinput></term>
          <listitem>
            <para>To define what content strings are indexed, set
              this attribute to an XPath expression that describes
              some content relative to the nodes described by the
              <userinput>match</userinput> attribute.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>For example, suppose you have a document with
        <sgmltag class="starttag">river</sgmltag> elements that
        have a <userinput>map</userinput> attribute
        that you'll be referring to elsewhere.  You might set up
        a key called <userinput
       >river-map-key</userinput> by placing this
        element inside your stylesheet:</para>
<programlisting><![CDATA[    <xsl:key name="river-map-key" match="river" use="@map"/>]]></programlisting>
    </section> <!--xsl-key-->
    <section id='xsl-decimal-format'>
      <title><sgmltag
        class="starttag">xsl:decimal-format</sgmltag>: Define a
        numeric format</title>
      <para>This is a top-level element; it can only occur as
        a child of the root element of your stylesheet.  It
        has two different functions:</para>
      <itemizedlist>
        <listitem>
          <para>If you provide a <userinput
           >name</userinput> attribute,
            you create a named numeric format that can be
            used in the <link
            linkend="format-number-func"><userinput
           >format-number()</userinput>
            function.</link></para></listitem>
        <listitem>
          <para>If you don't provide a <userinput
           >name</userinput> attribute, the
            it defines the default format used for
            all numbers.</para></listitem>
      </itemizedlist>
      <para>Aside from the <userinput
       >name</userinput> attribute, the other
        attributes are not discussed here.  They are chiefly
        useful for non-USA languages.  Refer to the
        <ulink url="http://www.w3.org/TR/xslt">XSLT
        specification</ulink> for more details.</para>
    </section> <!--xsl-decimal-format-->
  </section> <!--top-level-elts-->
  <section id='template-elts'>
    <title>Basic template elements</title>
    <para>Use the XSLT elements below to define templates that specify
      how to process selected input elements.</para>
    <section id='xsl-template'>
      <title><sgmltag class="starttag">xsl:template</sgmltag>:
        Define a template</title>
      <para>This is the basic tag specifying how to process
        some set of input.  There are two basic types of
        templates:</para>
      <itemizedlist>
        <listitem>
          <para>Templates with a <userinput
           >match="..."</userinput> attribute are
            applied to the input nodes that are selected by
            that attribute.</para></listitem>
        <listitem>
          <para>Templates with a <userinput
           >name="..."</userinput> attribute are
            called <firstterm>named templates</firstterm>.  They
            are invoked by explicitly calling them with the
            <sgmltag class="starttag">xsl:apply-templates</sgmltag>
            element.</para>
          <para>You must supply either a
            <userinput>match</userinput> attribute or a
            <userinput>name</userinput> attribute.</para></listitem>
      </itemizedlist>
      <para>Attributes of <sgmltag
        class="starttag">xsl:template</sgmltag>:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>match</userinput></term>
          <listitem>
            <para>An XPath expression that selects a set of nodes.
              For example,
              <userinput>match="trail"</userinput> specifies a
              template that matches all
              <sgmltag class="starttag">trail</sgmltag> elements.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>name</userinput></term>
          <listitem>
            <para>Instead of a <userinput>match</userinput>
              attribute, you can give your template a name and
              call it using
              <sgmltag class="starttag">xsl:call-template</sgmltag>.</para>
            <para>For example, if you have a template that looks like</para>
<programlisting><![CDATA[    <xsl:template name="add-links">]]></programlisting>
            <para>then you could call this template using</para>
<programlisting><![CDATA[    <xsl:call-template name="add-links"/>]]></programlisting>
            <para>You can also pass values to a named template using
              <sgmltag class="starttag">xsl:with-param</sgmltag>.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>mode</userinput></term>
          <listitem>
            <para>Sometimes you want to use the same content in
              more than one place.  For example, chapter titles
              might appear both at the beginning of a chapter and
              also in the table of contents.</para>
            <para>To do this, define a <userinput
             >mode="<replaceable>m</replaceable>"</userinput>
              attribute on the template for each place you use
              that content.  Then use <sgmltag
              class="starttag">xsl:apply-templates
              mode="<replaceable>m</replaceable>"...</sgmltag> to
              process the content with that mode.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-template-->
    <section id='xsl-variable'>
      <title><sgmltag class="starttag">xsl:variable</sgmltag>:
        Define a global or local variable</title>
      <para>You can define a variable and set its value using the
        <sgmltag class="starttag">xsl:variable</sgmltag>
        element.  Once you have defined a variable, you can refer
        to it in any XPath expression by using a dollar sign
        (<userinput>$</userinput>) followed by
        the name of a variable.</para>
      <para>There are two kinds of variables:</para>
      <itemizedlist>
        <listitem>
          <para>A <firstterm>global</firstterm> variable's value
            is available everywhere in your stylesheet.  To
            define a global variable, place the <sgmltag
            class="starttag">xsl:variable</sgmltag> element as a
            child of the root stylesheet element.</para></listitem>
        <listitem>
          <para>The value of a <firstterm>local</firstterm>
            variable is available only inside the element where
            it is declared.</para></listitem>
      </itemizedlist>
      <para>There are two ways to specify the value of your
        variable.  You can use an XPath expression in the <userinput
       >select</userinput> attribute and the
        variable will take on the value of that expression.  You
        can, instead, place the value in the content of the
        <sgmltag class="starttag">xsl:variable</sgmltag>
        element.  For example, these two elements have the same
        effect:</para>
<programlisting><![CDATA[    <xsl:variable name="child-page" select="'child.html'"/>
    <xsl:variable name="child-page">child.html</xsl:variable>]]></programlisting>
      <para>Note in the first example above that the value of the
        <userinput>select</userinput> attribute has
        two levels of quotes.  This is necessary because in XPath
        names usually refer to child elements.  If you want an
        attribute to have a string constant as its value, you
        must provide a second level of quotes inside the quotes
        that surround the attribute value.</para>
      <para>Here are the attributes of the <sgmltag
        class="starttag">xsl:variable</sgmltag> element:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>select</userinput></term>
          <listitem>
            <para>The value you are assigning to this variable.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-variable-->
    <section id='xsl-apply-templates'>
      <title><sgmltag
        class="starttag">xsl:apply-templates</sgmltag>: Process a
        node set with appropriate templates</title>
      <para>The purpose of this element is to tell the XSLT
        processor to find the templates that apply to a given set
        of elements, and apply them.  This happens a lot when you
        are writing the template to process a certain element,
        and you want to say &#x201c;now go and process all the children
        of this element, using whatever templates apply.&#x201d;
        Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>select</userinput></term>
          <listitem>
            <para>To specify which nodes you want to process, set
              this attribute's value to an XPath expression that
              computes a node-set.  Each node in the resulting
              set will be processed.  This attribute is optional;
              the default node-set consists of all the children
              of the current node.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>mode</userinput></term>
          <listitem>
            <para>This attribute is used when you want to process
              the same input content more than once in more than
              one way.  For example, if you have chapter titles
              in a document, you'll need to process them twice:
              once to put the title on the first page of the
              chapter, and also to build the table of contents.</para>
            <para>If you supply a mode attribute with your <sgmltag
              class="starttag">xsl:apply-template</sgmltag>
              element, it will only apply templates that have the
              same <userinput>mode</userinput>
              attribute.  In the example, you'd write a regular
              template (with no <userinput
             >mode</userinput> attribute) to
              process the chapter title as part of the chapter
              body, and you'd write another template as <sgmltag
              class="starttag">xsl:template
              mode="toc"...</sgmltag> to process the chapter
              title in the table of contents.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>Here are a couple of examples.  The most common
        usage, this means &#x201c;process all children using the
        appropriate templates.&#x201d;:</para>
<programlisting><![CDATA[    <xsl:apply-templates/>]]></programlisting>
      <para>And this example processes all <sgmltag
        class="starttag">map</sgmltag> children of the current
        node:</para>
<programlisting><![CDATA[    <xsl:apply-templates select="map"/>]]></programlisting>
    </section> <!--xsl-apply-templates-->
    <section id='xsl-include'>
      <title><sgmltag class="starttag">xsl:include</sgmltag>:
        Insert another stylesheet</title>
      <para>Another tool for modular XSLT programming is the
        <sgmltag class="starttag">xsl:include</sgmltag> tag,
        which effectively means &#x201c;insert another stylesheet
        here.&#x201d;  There is one attribute:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>href</userinput></term>
          <listitem>
            <para>To include another stylesheet, give its URI as
              the value of this attribute.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>There is a difference between importing and including
        a stylesheet.  The <link linkend="xsl-import"><sgmltag
        class="starttag">xsl:import</sgmltag></link> element
        lets you use templates from another stylesheet, but those
        templates have a lower priority and can be overridden by
        your templates.  If you use <sgmltag
        class="starttag">xsl:include</sgmltag>, though, any
        templates in the included stylesheet have the same
        priority as your other templates; it's as if that
        stylesheet were copied into the middle of your stylesheet.</para>
    </section> <!--xsl-include-->
    <section id='xsl-param'>
      <title><sgmltag class="starttag">xsl:param</sgmltag>:
        Define an argument to be passed into a template</title>
      <para>The template is the basic module or building block of
        the XSLT stylesheet.  The <sgmltag
        class="starttag">xsl:param</sgmltag> element allows you
        to write a template that can take argument (parameter)
        values.</para>
      <para>Each parameter to a template must have a unique name,
        supplied via the <userinput
       >name</userinput> attribute.</para>
      <para>When a template is applied, the values of its
        parameters are determined by this process:</para>
      <procedure>
        <step performance="required">
          <para>If the calling template supplies a value for the
            parameter by using an <sgmltag
            class="starttag">xsl:with-param</sgmltag>, the
            parameter will be set to that value.</para></step>
        <step performance="required">
          <para>If the calling template does not supply a value,
            but the <sgmltag class="starttag">xsl:param</sgmltag>
            element defines a default value, the parameter is set
            to that default value.</para></step>
        <step performance="required">
          <para>If the <sgmltag
            class="starttag">xsl:param</sgmltag> element of the
            template doesn't supply a default value, the
            parameter is set to an empty string.</para></step>
      </procedure>
      <para>There are two ways to specify the default value of
        a parameter.  You can supply the value as a <userinput
       >select</userinput> attribute, or you can
        put the value inside the content of the <sgmltag
        class="starttag">xsl:param</sgmltag> element.  So these
        two constructs work the same:</para>
<programlisting><![CDATA[    <xsl:param name="color" select="'green'"/>
    <xsl:param name="color">green</xsl:param>]]></programlisting>
      <para>Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>name</userinput> (required)</term>
          <listitem>
            <para>The name of this parameter.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>select</userinput></term>
          <listitem>
            <para>The default value for this parameter, if any.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-param-->
    <section id='xsl-with-param'>
      <title><sgmltag class="starttag">xsl:with-param</sgmltag>:
        Pass an argument to a template</title>
      <para>This element is used inside either <sgmltag
        class="starttag">xsl:call-template</sgmltag> or <sgmltag
        class="starttag">xsl:apply-templates</sgmltag> to pass
        argument (parameter) values to the called template.  The
        <userinput>name</userinput> attribute of
        this element must match one of the parameter names in the
        called template; see <link linkend="xsl-param"><sgmltag
        class="starttag">xsl:param</sgmltag></link>, above.
        Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>name</userinput> (required)</term>
          <listitem>
            <para>Specifies the name of the parameter to which we're
            passing the value.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>select</userinput></term>
          <listitem>
            <para>Specifies the value we're supplying to the
            parameter.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>If the <userinput>select</userinput>
        attribute is omitted, you can supply the value as
        content; otherwise, the element is empty.  These two
        constructs have the same effect:</para>
<programlisting><![CDATA[    <xsl:with-param name="color" select="'green'"/>
    <xsl:with-param name="color">green</xsl:with-param>]]></programlisting>
    </section> <!--xsl-with-param-->
  </section> <!--template-elts-->
  <section id='output-elts'>
    <title>Output instructions</title>
    <para>These elements are used to send various things to
      the output your stylesheet is producing.</para>
    <section id='xsl-text'>
      <title><sgmltag class="starttag">xsl:text</sgmltag>:
        Output literal text</title>
      <para>To send some text to the output, embed that text
        in the content of an <sgmltag
        class="starttag">xsl:text</sgmltag> element.  For
        example, this would send the text <userinput
       >"not"</userinput>, followed by a newline,
        followed by the text <userinput>"insane"</userinput>:</para>
<programlisting><![CDATA[    <xsl:text>not
insane</xsl:text>]]></programlisting>
      <para>There is one optional attribute:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>disable-output-escaping</userinput></term>
          <listitem>
            <para>For output to XML or HTML, special characters
            like <userinput>"&lt;"</userinput>
            are translated to their escaped equivalents, such as
            <userinput>"&amp;lt;</userinput>.  If your
            <sgmltag class="starttag">xsl:text</sgmltag> element
            has attribute
            <userinput>disable-output-escaping="yes"</userinput>,
            however, such characters will be sent as is, untranslated.
            The default value is
            <userinput>"no"</userinput>. This option is ignored
            for text output.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-text-->
    <section id='xsl-value-of'>
      <title><sgmltag class="starttag">xsl:value-of</sgmltag>:
        Output the value of an expresssion</title>
      <para>To output the string equivalent of some XPath
        expression, use this element.  Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>select</userinput> (required)</term>
          <listitem>
            <para>The XPath expression to be evaluated.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>disable-output-escaping</userinput></term>
          <listitem>
            <para>See <link linkend="xsl-text"><sgmltag
            class="starttag">xsl:text</sgmltag></link>.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>For example, suppose you have defined a variable
      named <userinput>lap-count</userinput> and
      it currently has a value of 32.  This element would place
      the text <userinput>"33"</userinput> in the
      output:</para>
<programlisting><![CDATA[    <xsl:value-of select="$lap-count+1"/>]]></programlisting>
    </section> <!--xsl-value-of-->
    <section id='xsl-element'>
      <title><sgmltag class="starttag">xsl:element</sgmltag>:
        Output an element</title>
      <para>In most cases it's pretty easy to output an element,
        say something like a <sgmltag
        class="starttag">fruit-basket</sgmltag> tag: you just
        put that tag in your template, and it gets written.</para>
      <para>However, sometimes you need to create an element
        whose name has to be computed using an XPath expression.
        The <sgmltag class="starttag">xsl:element</sgmltag> tag
        allows you to do this.  Here are the attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>name</userinput> (required)</term>
          <listitem>
            <para>Specifies the name of the element you are creating.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>namespace</userinput></term>
          <listitem>
            <para>If you want the element to be from a specific
              namespace, supply this attribute with the namespace
              as its value.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>use-attribute-sets</userinput></term>
          <listitem>
            <para>The name(s) of one or more <link
              linkend="xsl-attribute-set">attribute sets</link> that
              this element should carry.  If there are multiple
              attribute sets, their names should be separated by
              spaces.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>The content of the <sgmltag
        class="starttag">xsl:element</sgmltag> element in
        your stylesheet, after processing, becomes the content of
        the generated tag.</para>
      <para>Here are some examples.  Suppose that XSLT is
        processing a template that matches <sgmltag
        class="starttag">river</sgmltag> elements that have a
        <userinput>salinity</userinput>
        attribute.  You want to generate an element whose name is
        the same as the name of that attribute.  You want the
        content of the generated element to be the value of the node's
        <userinput>flow-rate</userinput>
        attribute.  This would do the trick:</para>
<programlisting><![CDATA[    <xsl:element name="@salinity">
      <xsl:value-of select="@flow-rate"/>
    </xsl:element>]]></programlisting>
    </section> <!--xsl-element-->
    <section id='xsl-attribute'>
      <title><sgmltag class="starttag">xsl:attribute</sgmltag>:
        Output an attribute</title>
      <para>The purpose of this tag is to add an attribute to an
        element, especially if the attribute name is something
        that has to be computed during processing.  The attribute
        is added to whatever element is being output at that
        point by your template.  Here are the attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>name</userinput> (required)</term>
          <listitem>
            <para>An XPath expression that specifies the attribute
            name.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>namespace</userinput></term>
          <listitem>
            <para>If used, the value of this attribute is
              prefixed to the attribute name as a namespace.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>Here's an example.  This generates a <sgmltag
        class="starttag">dish</sgmltag> element with an
        attribute whose namespace is <userinput
       >dl:</userinput>, whose attribute name
        is the value of the variable <userinput
       >dish-tag</userinput>, and whose value
        is the name of the <userinput
       >dish-lang</userinput> variable:</para>
<programlisting><![CDATA[    <dish>
      <xsl:attribute name="$dish-tag" namespace="'dl'">
        <xsl:value-of select="$dish-lang"/>
      </xsl:attribute>
    </dish>]]></programlisting>
    </section> <!--xsl-attribute-->
    <section id='xsl-number'>
      <title><sgmltag class="starttag">xsl:number</sgmltag>:
        Output an element number or formatted number</title>
      <para>Sometimes you want to number things, like chapters
        in a book, or section numbers in an outline (1, 1.1, 1.2,
        and so on).  That's what this element is for.  It can
        also be used to format a number derived from an XPath
        expression.</para>
      <para>The way elements are numbered depends on their
        position in a node-set.  For example, if you have an
        element called <sgmltag
        class="starttag">volume-set</sgmltag> whose children are
        <sgmltag class="starttag">volume</sgmltag> elements, the
        template for the <sgmltag
        class="starttag">volume-set</sgmltag> element will
        probably use this construct to format its children:</para>
<programlisting><![CDATA[    <xsl:apply-templates select="volume"/>]]></programlisting>
      <para>The <userinput
       >select="volume"</userinput> XPath
        expression produces a node-set containing the <sgmltag
        class="starttag">volume</sgmltag> children.  So, the
        template that formats the <sgmltag
        class="starttag">volume</sgmltag> element will get a node
        whose position in that set can be determined with the
        XPath function <userinput
       >position()</userinput>.  Then you'll need
        an <sgmltag class="starttag">xsl:number</sgmltag>
        construct to convert that position into a number in the
        output.</para>
      <para>This feature has a lot of attributes that let you
        control the format of the number, and even its
        value:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>value</userinput></term>
          <listitem>
            <para>If you just want to format the value of an XPath
            expression, use this attribute with the expression as
            its value.  For example, <sgmltag
            class="starttag">xsl:number
            value="$bat-count"/</sgmltag> would output the value
            of the <userinput
           >bat-count</userinput> variable.  If
            you want to number elements, though, don't use this
            attribute.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>count</userinput></term>
          <listitem>
            <para>An XPath pattern that selects the nodes that are
            counted.  For example, if you want your <sgmltag
            class="starttag">theorem</sgmltag> and <sgmltag
            class="starttag">lemma</sgmltag> tags to be
            counted on the same system, you can specify
            <userinput
           >count="theorem|lemma"</userinput>.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>level</userinput></term>
          <listitem>
            <para>This attribute controls whether we are
              numbering elements at just one level, or at
              multiple levels at once (such as an outline that
              has numbers like &#x201c;2.3.1.5&#x201d;).  Values are:
              <informaltable>
                <tgroup cols="2">
                  <colspec colwidth="1*" align="left"></colspec>
                  <colspec colwidth="4*" align="justify"></colspec>
                  <tbody>
                    <row>
                      <entry><userinput
                       >single</userinput></entry>
                      <entry>Only elements at the same level as
                        the current node are counted.</entry>
                    </row>
                    <row>
                      <entry><userinput
                       >multiple</userinput></entry>
                      <entry>Any ancestor nodes that match the <userinput
                       >count</userinput>
                        attribute are included to form a compount
                        number.  For example, if the current node
                        is the 4th child of the 1st child of the
                        3rd child of its ancestor nodes that
                        match the <userinput
                       >count</userinput> value,
                        the generated number will be <userinput
                       >3.1.4</userinput>.</entry>
                    </row>
                    <row>
                      <entry><userinput
                       >any</userinput></entry>
                      <entry>All the preceding and ancestor nodes
                        that match the <userinput
                       >count</userinput>
                        expression are counted in a single
                        sequence, and the number output is in
                        that sequence.</entry>
                    </row>
                  </tbody>
                </tgroup>
              </informaltable>
            </para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>format</userinput></term>
          <listitem>
            <para>The value of this attribute is a model for how
              the formatted number should look.  Values
              include:
              <informaltable>
                <tgroup cols="2">
                  <colspec colwidth="1*" align="left"></colspec>
                  <colspec colwidth="4*" align="justify"></colspec>
                  <tbody>
                    <row>
                      <entry><userinput
                       >"1"</userinput></entry>
                      <entry>Use Arabic numerals.  You can supply
                        leading zeroes if you like, so a value of
                        <userinput
                       >"001"</userinput> would
                        fill each number with up to two leading
                        zeroes.</entry>
                    </row>
                    <row>
                      <entry><userinput
                       >"a"</userinput></entry>
                      <entry>Use lowercase letters.  The sequence is a, b,
                        c, ..., z, aa, ab, ... and so on.</entry>
                    </row>
                    <row>
                      <entry><userinput
                       >"A"</userinput></entry>
                      <entry>Use capital letters.</entry>
                    </row>
                    <row>
                      <entry><userinput
                       >"i"</userinput></entry>
                      <entry>Use lowercase Roman numerals.</entry>
                    </row>
                    <row>
                      <entry><userinput
                       >"I"</userinput></entry>
                      <entry>Use uppercase Roman numerals.</entry>
                    </row>
                  </tbody>
                </tgroup>
              </informaltable>
            </para>
            <para>You can also supply trailing punctuation, so
              for example <userinput>format="1:
              "</userinput> would follow each number with a colon
              and space.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>There are some other attributes, not discussed here,
        that are useful for non-USA usages.  Refer to the
        <ulink url="http://www.w3.org/TR/xslt">XSLT
        specification</ulink> for more details.</para>
    </section> <!--xsl-number-->
  </section> <!--output-elts-->
  <section id='branching-elts'>
    <title>Branching elements</title>
    <para>The elements described in this section all you to
      iterate over a set of nodes, and also to provide processing
      that happens only in certain cases.</para>
    <section id='xsl-for-each'>
      <title><sgmltag class="starttag">xsl:for-each</sgmltag>:
        Iterate over a set of nodes</title>
      <para>To do the same thing to each node in a node set, use
        the <sgmltag class="starttag">xsl:for-each</sgmltag>
        construct.  Stuff inside this element gets done once for
        each element in the node-set.  There is one
        attribute:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>select</userinput> (required)</term>
          <listitem>
            <para>An XPath expression that specifies the node-set
              over which you want to iterate.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>For example, suppose you are writing a template with
        child elements of types <sgmltag
        class="starttag">daughter</sgmltag> and <sgmltag
        class="starttag">son</sgmltag>.  This element would
        process all the children of either type:</para>
<programlisting><![CDATA[    <xsl:for-each select="daughter|son">...</xsl:for-each>]]></programlisting>
    </section> <!--xsl-for-each-->
    <section id='xsl-if'>
      <title><sgmltag class="starttag">xsl:if</sgmltag>:
        Conditional processing</title>
      <para>Sometimes you want to perform an action only when a
        certain condition is met.  The <sgmltag
        class="starttag">xsl:if</sgmltag> tag does this
        conditional processing.  This is XSLT's single-branch
        &#x201c;if&#x201d; construct; there is no two-branch form.  If you
        want to perform one thing if a condition is true, and a
        different thing if that condition is false, you'll have
        to use the <link linkend="xsl-choose"><sgmltag
        class="starttag">xsl:choose</sgmltag> construct</link>.
        There is one required attribute:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>test</userinput></term>
          <listitem>
            <para>This XPath expression is evaluated.  If it is
              true, the content of the <sgmltag
              class="starttag">xsl:if</sgmltag> element is
              processed, otherwise that content is not processed.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>Here's an example.  This writes the value of
        variable <userinput
       >head-count</userinput> to the output, but
        only if it is an odd number:</para>
<programlisting><![CDATA[    <xsl:if test="($head-count mod 2)=1">
      <xsl:value-of select="$head-count"/>
    </xsl:if>]]></programlisting>
    </section> <!--xsl-if-->
    <section id='xsl-choose'>
      <title><sgmltag class="starttag">xsl:choose</sgmltag>:
      The multiple-case construct</title>
      <para>To produce output with two or more different cases,
        use the <sgmltag class="starttag">xsl:choose</sgmltag>
        construct.  It has one <sgmltag
        class="starttag">xsl:when</sgmltag> element for each
        case, plus an optional <sgmltag
        class="starttag">xsl:otherwise</sgmltag> element at the
        end for the &#x201c;none of the above&#x201d; case.  Each <sgmltag
        class="starttag">xsl:when</sgmltag> element has a
        <userinput>test</userinput> attribute whose
        value is an XPath expression; the first one that evaluates
        to a true value is processed.</para>
      <para>Here's an example that outputs the content of the <sgmltag
        class="starttag">turtle</sgmltag>children of the current
        node, and puts the first one in parentheses and the last
        one in square brackets.</para>
<programlisting><![CDATA[    <xsl:for-each select="turtle">
      <xsl:choose>
        <xsl:when test="position() = 1">
          <xsl:text>(</xsl:text>
          <xsl:apply-templates select="."/>
          <xsl:text>)</xsl:text>
        </xsl:when>
        <xsl:when test="position() = count()">
          <xsl:text>[</xsl:text>
          <xsl:apply-templates select="."/>
          <xsl:text>]</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:apply-templates select="."/>
        </xsl:otherwise>
      </xsl:choose>      
    </xsl:for-each>]]></programlisting>
    </section> <!--xsl-choose-->
    <section id='xsl-call-template'>
      <title><sgmltag class="starttag">xsl:call-template</sgmltag>: Invoke
        another template</title>
      <para>You can package up bits of XSLT in named templates,
        and call those templates with the <sgmltag
        class="starttag">xsl:call-template</sgmltag> construct.
        Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>name</userinput> (required)</term>
          <listitem>
            <para>The name of the template you are calling.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>If you want to pass arguments (parameters) to the
        template, use one <link linkend="xsl-with-param"><sgmltag
        class="starttag">xsl:with-param</sgmltag></link> element
        for each value you want to pass.</para>
    </section> <!--xsl-call-template-->
  </section> <!--branching-elts-->
  <section id='advanced-elts'>
    <title>Advanced elements</title>
    <para>The elements in this section round out the set of
      XSLT elements.  These elements are used less often but
      may be helpful in certain cases.</para>
    <section id='xsl-apply-imports'>
      <title><sgmltag
        class="starttag">xsl:apply-imports</sgmltag>: Use an overridden
        template</title>
      <para>You can use templates that you have imported using
        the <link linkend="xsl-import"><sgmltag
        class="starttag">xsl:import</sgmltag> tag</link>, but you
        can also override them by providing your own template.
        The <userinput>&lt;xsl:apply-imports/&gt;</userinput>
        tag allows you to use an imported template even if you
        have overridden it.</para>
      <para>There are no attributes and no content.  The template
        you are invoking is the one overridden by the current
        template.</para>
    </section> <!--xsl-apply-imports-->
    <section id='xsl-attribute-set'>
      <title><sgmltag class="starttag">xsl:attribute-set</sgmltag>: Define a
        named attribute set</title>
      <para>Often you will want to add one or more attributes to
        an element you are generating with the <sgmltag
        class="starttag">xsl:element</sgmltag> tag.  The <sgmltag
        class="starttag">xsl:attribute-set</sgmltag> element lets
        you create a named set of attributes so you can add them
        merely by referring to that name with the <userinput
       >use-attribute-sets</userinput> attribute
        of <sgmltag class="starttag">xsl:element</sgmltag>.</para>
      <para>Use one or more <sgmltag
        class="starttag">xsl:attribute</sgmltag> children as the
        content of this element.  Those attributes and their
        values make up the attributes in the set.</para>
      <para>Attributes of <sgmltag
        class="starttag">xsl:attribute-set</sgmltag>
        include:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>name</userinput> (required)</term>
          <listitem>
            <para>Gives this attribute set a name.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>use-attribute-sets</userinput></term>
          <listitem>
            <para>Any attribute sets named in this value become
              part of the attribute set you are creating.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-attribute-set-->
    <section id='xsl-comment'>
      <title><sgmltag class="starttag">xsl:comment</sgmltag>:
        Output a comment</title>
      <para>To write a comment to the output, use this element.
        The content of the element becomes the content of the
        comment.  There are no attributes.  For example, this
        element in a template:</para>
<programlisting>    &lt;xsl:comment&gt;Do not edit this file; it is generated
      automatically by an XSLT script.&lt;/xsl:comment&gt;</programlisting>
      <para>would generate this comment in the output:</para>
      <programlisting><![CDATA[    <!--Do not edit this file; it is generated
      automatically by an XSLT script.-->]]></programlisting>
    </section> <!--xsl-comment-->
    <section id='xsl-copy'>
      <title><sgmltag class="starttag">xsl:copy</sgmltag>:
        Shallow copying</title>
      <para>The current node is copied in the corresponding location
        of the output, but its children, and any attributes it may
        have, are not copied.  There is one optional attribute:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>use-attribute-sets</userinput></term>
          <listitem>
            <para>You can attach attributes to the new copy of
              the node by specifying a value for this attribute
              the names of one or more named attribute sets.
              See the section on <link
              linkend="xsl-attribute-set">named attribute
              sets</link>.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-copy-->
    <section id='xsl-copy-of'>
      <title><sgmltag class="starttag">xsl:copy-of</sgmltag>:
        Deep copying</title>
      <para>To copy an entire subtree of the input document,
        use this tag with a <userinput>select</userinput>
        attribute that describes a node-set.  The nodes in
        that node-set will be added to the output, ordered in the
        same way they are in the input document.  Also, any
        attributes of those nodes, and their children and all
        descendants, are recursively copied in the same way.</para>
    </section> <!--xsl-copy-of-->
    <section id='xsl-fallback'>
      <title><sgmltag class="starttag">xsl:fallback</sgmltag>:
        What to do if an extension is missing</title>
      <para>If you are trying to use an XSLT extensions (see
        <link linkend="extension-elts">extension elements</link>,
        below), and the extension can't be found, you can provide
        an <sgmltag class="starttag">xsl:fallback</sgmltag>
        element to specify what actions should be taken.  For
        example, this fragment shows a reference to an
        extension element named <sgmltag
        class="starttag">exsl:document</sgmltag>.  If that
        element is not available, it writes a message and
        terminates:</para>
<programlisting><![CDATA[    <exsl:document href="page.html">
      <xsl:fallback>
        <xsl:message terminate="yes">
          Aieeee! The exsl:document package is missing!
          I'm out of here!
        </xsl:message>
      </xsl:fallback>
    </exsl:document>]]></programlisting>
    </section> <!--xsl-fallback-->
    <section id='xsl-message'>
      <title><sgmltag class="starttag">xsl:message</sgmltag>:
        Write a debugging message</title>
      <para>This element writes its content to the standard
        output stream (not to the output document).  For an
        example, see <link linkend="xsl-fallback"><sgmltag
        class="starttag">xsl:fallback</sgmltag></link> above.
        Attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>terminate</userinput></term>
          <listitem>
            <para>If you use <userinput
           >terminate="yes"</userinput>, the XSLT
            processor will stop execution after writing the
            message.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--xsl-message-->
    <section id='xsl-namespace-alias'>
      <title><sgmltag
        class="starttag">xsl:namespace-alias</sgmltag>: Assign a
        prefix to a namespace</title>
      <para>This is a pretty obscure feature.  It has only one
        use: writing an XSLT script that generates another XSLT
        script.</para>
      <para>Since normally any tag whose name starts with <userinput
       >xsl:</userinput> is processed, we have to
        provide a way to output a tag in the <userinput
       >xsl:</userinput> namespace without
        processing it.  The way we do this involves two steps:</para>
      <procedure>
        <step performance="required">
          <para>You must declare two different prefixes
            for the <userinput>xsl:</userinput>
            namespace in the attributes of the <sgmltag
            class="starttag">xsl:stylesheet</sgmltag> tag.  One
            prefix is declared as <userinput
           >xsl:</userinput>; you will use this
            namespace for the elements that you want to process
            as part of your stylesheet.  The other prefix is used
            to refer to the elements that you want to write to
            the output document.</para></step>
        <step performance="required">
          <para>You must provide a top-level <sgmltag
            class="starttag">xsl:namespace-alias</sgmltag>
            element with a <userinput
           >stylesheet-prefix</userinput>
            attribute whose value is the other prefix (besides
            <userinput>xsl:</userinput>), and
            whose <userinput
           >result-prefix</userinput> attribute
            is <userinput>"xsl"</userinput>.</para></step>
      </procedure>
      <para>For example, suppose your stylesheet starts this way:</para>
<programlisting><![CDATA[    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:out-xsl=""http://www.w3.org/1999/XSL/Transform">

      <xsl:output method="xml"/>
      <xsl:namespace-alias stylesheet-prefix="out-xsl"
        result-prefix="xsl"/>
      ...]]></programlisting>
      <para>then elements in your stylesheet with namespace
        <userinput>xsl:</userinput> will be
        processed, and elements with namespace <userinput
       >out-xsl:</userinput> will be written to
        the output document.</para>
    </section> <!--xsl-namespace-alias-->
    <section id='xsl-processing-instruction'>
      <title><sgmltag
      class="starttag">xsl:processing-instruction</sgmltag>:
        Output a processing instruction</title>
      <para>Use this element to output a processing instruction
        (<userinput
     >&lt;?<replaceable>target</replaceable>
      <replaceable>properties</replaceable>?&gt;</userinput>).
        Use the <userinput>name</userinput>
        attribute to generate the
        <replaceable>target</replaceable> portion; the content of
        the element becomes the
        <replaceable>properties</replaceable> portion.</para>
    </section> <!--xsl-processing-instruction-->
    <section id='xsl-sort'>
      <title><sgmltag class="starttag">xsl:sort</sgmltag>:
        Process nodes in a given order</title>
      <para>This element is used just inside the start of either
        an <sgmltag
        class="starttag">xsl:apply-templates</sgmltag> element or
        a <sgmltag class="starttag">xsl:for-each</sgmltag>
        element.   It has the effect of sorting the nodes in the
        parent element's node-set, so that the content is
        presented sorted according to some aspect of the content.</para>
      <para>You can use multiple <sgmltag
        class="starttag">xsl:sort</sgmltag> elements to specify
        multiple sort keys.  That is, if there are two <sgmltag
        class="starttag">xsl:sort</sgmltag> elements, the first
        one specifies the primary key, and the second one the
        secondary sort key (to be used in comparing items that
        have the same value for the primary key).</para>
      <para>The sort is <firstterm>stable</firstterm>, that is,
        if two items are equal in all key values, they will be in
        the same order as they were in the original
        document.</para>
      <para>Here are the attributes:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>select</userinput></term>
          <listitem>
            <para>An XPath expression that selects the nodes to be
            sorted.  The default value is the node-set of the
            parent element.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>data-type</userinput></term>
          <listitem>
            <para>Use a value of <userinput
           >"text"</userinput> to treat the items
            as text strings, or a value of <userinput
           >"number"</userinput> to treat them as
            numbers.  Default is <userinput>"text"</userinput>.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>order</userinput></term>
          <listitem>
            <para>Use <userinput
           >"asc"</userinput> for ascending order
            (this is the default), or <userinput
           >"desc"</userinput> for descending
            order.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>case-order</userinput></term>
          <listitem>
            <para>Specifies how to compare uppercase and
            lowercase letters.  A value of
            <userinput>"upper-first"</userinput> forces
            uppercase letters before lowercase ones; the opposite
            is <userinput>"lower-first"</userinput>.</para>
            <para>The default is language-dependent.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>lang</userinput></term>
          <listitem>
            <para>Defines the language to be used in sorting.
            See the <ulink
            url="http://www.ietf.org/rfc/rfc1766.txt">definition
            of the language codes</ulink> online.</para>
          </listitem>
        </varlistentry>
      </variablelist>
      <para>Here's an example.  Suppose you have <sgmltag
        class="starttag">person</sgmltag> elements that have
        children named <sgmltag
        class="starttag">surname</sgmltag> (containing the
        person's last name) and <sgmltag
        class="starttag">first-name</sgmltag> (containing the
        person's given name).  You want to process them in order
        by last name, using the first name as a tiebreaker.  Here
        is a stylesheet fragment that does this:</para>
<programlisting><![CDATA[    <xsl:for-each select="person">
      <xsl:sort select="surname"/>
      <xsl:sort select="first-name"/>
      <xsl:apply-templates select="."/>
    </xsl:for-each>]]></programlisting>
    </section> <!--xsl-sort-->
  </section> <!--advanced-elts-->
  <section id='xslt-functions'>
    <title>XSLT functions</title>
    <para>In addition to the <link
      linkend="xpath-functions-sect">XPath functions</link> defined
      above, XSLT supplies a number of additional functions.</para>
    <section id='current-func'>
      <title><userinput>current()</userinput>:
        Return the current node</title>
      <para>The <userinput>current()</userinput>
        function returns a node-set containing only the current
        (context) node.
        In most situations, this is exactly the same result as
        the XPath expression <userinput
       >"."</userinput>, but there is one case
        with a very important difference.</para>
      <para>Recall that XPath expressions can have several levels
        of selection.  For example, the XPath expression
        <userinput>"park/tree"</userinput>
        selects <sgmltag class="starttag">park</sgmltag> children
        of the context node, and then it selects <sgmltag
        class="starttag">tree</sgmltag> children of
        <emphasis>those</emphasis> nodes.  So at each stage of
        evaluation of that XPath expression, <userinput
       >"."</userinput> has a different meaning:
        at each stage it means the set of nodes selected so far.</para>
      <para>The critical difference in the <userinput
       >current()</userinput> function is that it
        always refers to the node that was the context node
        before any of the XPath expression was evaluated.</para>
    </section> <!--current-func-->
    <section id='document-func'>
      <title><userinput>document()</userinput>:
        Pull in content from other documents</title>
      <para>There is one optional argument:</para>
<programlisting>    document(<replaceable>uri</replaceable>)</programlisting>
      <para>where <replaceable>uri</replaceable> is the
        URI of a document.  The return value is
        a node-set containing that document as a tree.  If the
        argument is an empty string (<userinput
       >'document("")'</userinput>), you get back
        your own stylesheet (the one in which the <userinput
       >document()</userinput> call occurs)
        as a tree.  This allows you to access
        content in another document (or your stylesheet) the same
        way you'd access the content of the input document: write
        template rules for that content and invoke it with
        <sgmltag
        class="starttag">xsl:apply-templates</sgmltag> or
        <sgmltag class="starttag">xsl:call-template</sgmltag>.</para>
    </section> <!--document-func-->
    <section id='format-number-func'>
      <title><userinput
       >format-number()</userinput>: Convert a
        number to a string</title>
      <para>This function takes two required arguments and a
        third optional argument:</para>
<programlisting>    format-number(<replaceable>n</replaceable
                >, <replaceable>p</replaceable
                > [,<replaceable>f</replaceable>])</programlisting>
      <para>where:</para>
      <informaltable>
        <tgroup cols="2">
          <colspec colwidth="1*"></colspec>
          <colspec colwidth="8*"></colspec>
          <tbody>
            <row>
              <entry><userinput
             ><replaceable>n</replaceable></userinput></entry>
              <entry><simpara>is the number to be formatted</simpara></entry>
            </row>
            <row>
              <entry><userinput
               ><replaceable>p</replaceable
                ></userinput></entry>
              <entry><simpara>is a format pattern string using
                the characters described below</simpara></entry>
            </row>
            <row>
              <entry><userinput
             ><replaceable>f</replaceable></userinput></entry>
              <entry><simpara>if supplied, this is the name of a named
              <sgmltag class="starttag">xsl:decimal</sgmltag>
              format item that will be used to determine
              internationalization features of the formatting,
              such as the grouping separator.</simpara></entry>
            </row>
          </tbody>
        </tgroup>
      </informaltable>
      <para>Here are the characters used in the formatting pattern
      <userinput><replaceable>p</replaceable></userinput>:</para>
      <table id='format-chars'>
        <title>Format pattern characters for <userinput
       >format-number()</userinput></title>
        <tgroup cols="2">
          <colspec colwidth="1*"></colspec>
          <colspec colwidth="8*"></colspec>
          <tbody>
            <row>
              <entry><userinput>#</userinput></entry>
              <entry>Denotes a digit.  Leading and trailing
              zeroes (and a trailing decimal, if any) will disappear.</entry>
            </row>
            <row>
              <entry><userinput>0</userinput></entry>
              <entry>Denotes a digit, but a digit always appears,
                even if it is a zero.</entry>
            </row>
            <row>
              <entry><userinput>-</userinput></entry>
              <entry>Shows the position of the minus sign.</entry>
            </row>
            <row>
              <entry><userinput>.</userinput></entry>
              <entry>Shows the position of the decimal point.</entry>
            </row>
            <row>
              <entry><userinput>,</userinput></entry>
              <entry>Positions the grouping separator for thousands.  For
                example, <userinput
               >"##,###.00"</userinput>.</entry>
            </row>
            <row>
              <entry><userinput>%</userinput></entry>
              <entry>Multiplies the number by one hundred and
                displays it as a percentage.</entry>
            </row>
            <row>
              <entry><userinput>;</userinput></entry>
              <entry>You can supply two patterns separated by a
              semicolon; the first one will be used for positive
              numbers and the second for negative numbers.</entry>
            </row>
            <row>
              <entry>other</entry>
              <entry>Literal characters are carried through to
                the result.</entry>
            </row>
          </tbody>
        </tgroup>
      </table>
    </section> <!--format-number-func-->
    <section id='generate-id-func'>
      <title><userinput
       >generate-id()</userinput>:  Generate a unique
        identifier</title> 
      <para>The purpose of this function is to generate a string
        of characters that uniquely identifies a node.  Such
        values are useful for attributes of type ID.</para>
      <para>The function takes one optional argument, a node-set:</para>
      <programlisting>    generate-id(<replaceable>S</replaceable
                >)</programlisting>
      <para>where <replaceable>S</replaceable> is a node-set.  If
        <replaceable>S</replaceable> is not given, the function
        generates an identifier for the context node.  If
        <replaceable>S</replaceable> is empty, the function
        returns an empty string.  If <replaceable>S</replaceable>
        contains more than one node, the function operates on the
        one that occurs first in the document.</para>
      <para>Within a given execution, this function will always
        produce the same value for a given node.  There is no
        guarantee that it will produce the same value on a
        different execution of the stylesheet.</para>
    </section> <!--generate-id-func-->
    <section id='key-func'>
      <title><userinput>key()</userinput>: Refer
        to an index entry</title>
      <para>This function is used to retrieve a set of nodes from
        anywhere in the document, using the index specified
        elsewhere by an <link linkend="xsl-key"><sgmltag
        class="starttag">xsl:key</sgmltag> element</link>.</para>
      <para>The calling sequence is:</para>
      <programlisting>    key(<replaceable>keyName</replaceable
                >, <replaceable>keyValue</replaceable> )</programlisting>
      <para>where <replaceable>keyName</replaceable> matches the
        <userinput>name</userinput> attribute of
        an <sgmltag class="starttag">xsl:key</sgmltag> element,
        and <replaceable>keyValue</replaceable> is a string.
        The result is a node-set containing all the nodes whose
        value for that key matches
      <replaceable>keyValue</replaceable>.</para>
      <para>Here's an example.  Suppose we declare a key like
        this:</para>
<programlisting><![CDATA[    <xsl:key name="river-map-key" match="river" use="@map"/>]]></programlisting>
      <para>Then we might process a set of <sgmltag
      class="starttag">river</sgmltag> elements that have an
      attribute <userinput>map="Elfego"</userinput> with this query:</para>
<programlisting><![CDATA[    <xsl:apply-templates select="key('river-map-key', 'Elfego')"/>]]></programlisting>
    </section> <!--key-func-->
    <section id='system-property-func'>
      <title><userinput
       >system-property()</userinput>: Return a
        system property value</title>
      <para>The purpose of this function is to interrogate
        certain properties of the XSLT processor.  The calling
        sequence is:</para>
<programlisting>    system-property(<replaceable>name</replaceable
                >)</programlisting>
      <para>where <replaceable>name</replaceable> is the name
        of a property.  The function returns the value of the
        named property.  In addition to any names that the XSLT
        processor may support, all processors must return values
        for these property names:</para>
      <variablelist>
        <varlistentry>
          <term><userinput>xsl:version</userinput></term>
          <listitem>
            <para>A number representing the supported version of
              XSLT.  At the moment, it will probably return 1.0.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>xsl:vendor</userinput></term>
          <listitem>
            <para>The name of the vendor that built the XSLT
              processor.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term><userinput>xsl:vendor-url</userinput></term>
          <listitem>
            <para>The URL of the vendor's homepage.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section> <!--system-property-func-->
  </section> <!--xslt-functions-->
  <section id='builtins'>
    <title>Built-in templates</title>
    <para>
      XSLT supplies several built-in, default templates.  These
      templates make it unnecessary to write templates for every
      possible situation; you need write templates only for the
      specific nodes you want to process.
    </para>
    <para>
      The first built-in template operates on any document node
      (<code >/</code >) or any element node (<code >*</code >)
      that doesn't have a more specific template.  It uses <code
      >xsl:apply-templates</code > so that its child elements
      will be processed.
    </para>
    <programlisting
><![CDATA[<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>]]>
</programlisting>
    <para>
      If you are using modes, the equivalent of this template
      also operates for any document or element node.  For
      example, if you use a mode called &#x201c;<code >toc</code
      >&#x201d; somewhere, XSLT will supply a template that works
      like this:
    </para>
    <programlisting
><![CDATA[<xsl:template match="*|/" mode="toc">
  <xsl:apply-templates mode="toc"/>
</xsl:template>]]>
</programlisting>
    <para>
      Another built-in template operates for any text or
      attribute nodes without more specific templates.  It has
      the effect of copying any text to the output by default.
    </para>
    <programlisting
><![CDATA[<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>]]>
</programlisting>
    <para>
      Finally, this built-in template has the effect of ignoring
      comments and processing instructions.
    </para>
    <programlisting
><![CDATA[<xsl:template match="processing-instruction()|comment()"/>]]>
</programlisting>
  </section> <!--builtins-->
  <section id='extension-elts'>
    <title>Extension elements</title>
    <para>You may need functions that are not part of standard
      XSLT.  A number of organizations have defined so-called
      <firstterm>extension elements</firstterm> that provide
      these additional functions.</para>
    <para>To use an extension, you must add two attributes to the <sgmltag
      class="starttag">xslt:stylesheet</sgmltag> element of
      your stylesheet:</para>
    <procedure>
      <step performance="required">
        <para>Declare a namespace for the extension elements
          by adding an attribute of the form
          <userinput
         >xmlns:<replaceable>n</replaceable
          >="<replaceable>u</replaceable>"</userinput>,
          where <replaceable>n</replaceable> is the namespace you
          are declaring, and <replaceable>u</replaceable> is the
          URI of the extension element's definition.</para></step>
      <step performance="required">
        <para>Tell XSLT to process this namespace, instead of
          writing it to the output, by using an attribute of the
          form <userinput
         >extension-element-prefixes="<replaceable
          >n</replaceable>"</userinput>, where
          <replaceable>n</replaceable> is the same namespace name
          used in the previous step.</para></step>
      </procedure>
    <para>We'll just give one example; more extensions will
      arise as XSLT evolves.</para>
    <section id='exslt-document'>
      <title>The <userinput
       >exsl:document</userinput> extension</title>
      <para>With stock XSLT, all output goes to one place:  the
        output document.  However, an organization called EXSLT
        has published an extension element that allows you to
        sent output to other files.  See the
        <ulink url="http://www.exslt.org/howto.html">EXSLT
        homepage</ulink> for more information.</para>
      <para>Here is an example of an <sgmltag
        class="starttag">xsl:stylesheet</sgmltag> element that
        includes the attributes necessary to use the <userinput
       >exsl:document</userinput> extension:</para>
<programlisting><![CDATA[    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:exsl="http://exslt.org/common"
      extension-element-prefixes="exsl">]]></programlisting>
      <para>Once you have done this, in order to write some
        content to a file named <replaceable>F</replaceable>,
        embed that content in an element that looks like this:</para>
<programlisting>    &lt;exsl:document href="<replaceable>F</replaceable>"&gt;
      ...
    &lt;/exsl:document&gt;</programlisting>
    </section> <!--exslt-document-->
  </section> <!--extension-elts-->
  <section id='xsltproc-sect'>
    <title>Using the <userinput>xsltproc</userinput>
      processor</title>
    <para>Before you try to apply your XSLT script, you may want to
      validate the XML file against its DTD.  To do this, use the
      <userinput>xmllint</userinput> program:</para>
<programlisting>    xmllint --valid --noout <replaceable>filename</replaceable>.xsl</programlisting>
    <para>where
      <filename><replaceable>filename</replaceable>.xsl</filename>
      is the name of your XML file.  Make sure your DTD is in the
      same directory and named in a
      <userinput>&lt;!DOCTYPE ...&gt;</userinput> declaration.</para>
    <para>For example, if your XML document uses a DTD named
      <userinput>trails.dtd</userinput> and its root element
      is <sgmltag class="starttag">trails</sgmltag>,
      its first line should look like this:</para>
<programlisting><![CDATA[    <!DOCTYPE trails SYSTEM "trails.dtd">]]></programlisting>
    <para>To transform a file using XSLT, use
      <userinput>xsltproc</userinput>:</para>
    <programlisting>    xsltproc -o <replaceable>output</replaceable
                >.html <replaceable>stylesheet</replaceable
                >.xsl <replaceable>file</replaceable>.xml</programlisting>
    <para>where <userinput><replaceable>stylesheet</replaceable
      >.xsl</userinput> is the XSLT stylesheet,
      <userinput><replaceable>file</replaceable>.xml</userinput>
      is the XML input file, and
      <userinput><replaceable>output</replaceable>.html</userinput>
      is the output file to be written.</para>
  </section> <!--xsltproc-sect-->
</article>
