Multiple Templates

<xsl:apply-templates>

<xsl:apply-templates> is similar to <xsl:value-of> in that it replaces itself with data, but where <xsl:value-of> copies data from an XPath expression evaluated in the current context, <xsl:apply-templates> copies data produced by whichever template rule matches the selected nodes. Its select attribute is optional; when omitted, the children of the context node are processed. The example below applies a shared template to both <Name> and <Age> elements, inserting a comma between sibling values.

<?xml version="1.0" encoding="UTF-8"?>
<Root>
   <Employee>
      <Name>Dash</Name>
      <Age>23</Age>
   </Employee>
   <Employee>
      <Name>Gwen</Name>
      <Age>22</Age>
   </Employee>
</Root>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="/Root">
      <Root>
         <Employee>
            <Name>
                <xsl:apply-templates select="Employee/Name"/>
            </Name>
            <Age>
                <xsl:apply-templates select="Employee/Age"/>
            </Age>
         </Employee>
      </Root>
   </xsl:template>
   <xsl:template match="Name|Age">
      <xsl:value-of select="."/>
      <xsl:if test="position()!=last()">
         <xsl:text>,</xsl:text>
      </xsl:if>
   </xsl:template>
</xsl:stylesheet>

Dash,Gwen 23,22
The same result can be obtained more simply with <xsl:value-of separator="," select="…"/>.

<xsl:apply-templates> can contain <xsl:sort> and <xsl:with-param> as child elements, and can carry a mode (token) attribute. It can also be used to execute a multi-staged pipeline of transformations, as in the example below, which sorts a tree of directory/file nodes and then discards deeper nesting by re-matching inner nodes against a more specific pattern.

<?xml version="1.0" encoding="UTF-8"?>
<treeview>
  <treenode>
    <caption>Directory Z</caption>
    <nodes>
      <treenode><caption>File B</caption></treenode>
      <treenode><caption>File Z</caption></treenode>
      <treenode><caption>File A</caption></treenode>
    </nodes>
  </treenode>
  <treenode>
    <caption>Directory G</caption>
    <nodes>
      <treenode><caption>File F</caption></treenode>
      <treenode><caption>File O</caption></treenode>
      <treenode><caption>File B</caption></treenode>
    </nodes>
  </treenode>
</treeview>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />
   <xsl:template match="/">
      <treeview>
         <xsl:apply-templates select="treeview/treenode">
            <xsl:sort select="caption" data-type="text"/>
         </xsl:apply-templates>
      </treeview>
   </xsl:template>
   <xsl:template match="treenode">
      <treenode>
         <xsl:copy-of select="caption"/>
         <nodes>
            <xsl:apply-templates select="nodes/treenode">
               <xsl:sort select="caption" data-type="text"/>
            </xsl:apply-templates>
         </nodes>
      </treenode>
   </xsl:template>
   <xsl:template match= "/treeview/treenode/nodes/treenode">
      <xsl:copy-of select="."/>
   </xsl:template>
</xsl:stylesheet>

Directory G File B File F File O Directory Z File A File B File Z

<xsl:next-match>

<xsl:next-match> is similar to <xsl:apply-templates> in that it invokes another matching template, but unlike <xsl:apply-templates>, which builds on the current context, <xsl:next-match> resets the context and excludes the current template rule from the next match. Note that this makes it possible to build a recursive chain of templates, as shown below where an element with several boolean attributes is progressively wrapped by the templates matching each attribute, in priority order.

<?xml version="1.0" encoding="UTF-8"?>
<element bold="true"
               subscript="false"
               italic="true"
               text="stuff"/>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:template match="element" priority="1">
      <xsl:value-of select="@text" />
   </xsl:template>
   <xsl:template match="element[@italic = 'true']"
                        priority="2">
      <sup><xsl:next-match/></sup>
   </xsl:template>
   <xsl:template match="element[@subscript = 'true']"
                        priority="3">
      <sub><xsl:next-match/></sub>
   </xsl:template>
   <xsl:template match="element[@bold = 'true']"
                        priority="4">
     <strong><xsl:next-match/></strong>
   </xsl:template>
</xsl:stylesheet>

stuff

<xsl:call-template>, <xsl:context-item>

<xsl:call-template> invokes a named template directly, independent of the current node's matching rules, passing parameters with <xsl:with-param>.

<?xml version="1.0" encoding="UTF-8"?>
<a>
  <b>1<c/>a</b>
  <b>2<c/>b</b>
  <b>3<c/>c</b>
  <b>4<c/>d</b>
</a>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:fn="http://www.w3.org/2005/xpath-functions">
   <xsl:template name="T">
     <xsl:context-item as="node()"/>
     <xsl:param name="P"/>
     <xsl:apply-templates select="b[position() lt 3]"/>
     <xsl:value-of select="$P"/>
   </xsl:template>
   <xsl:template match="a">
      <xsl:call-template name="T">
        <xsl:with-param name="P" select="'X'"/>
      </xsl:call-template>
   </xsl:template>
</xsl:stylesheet>

1a2bX
<xsl:context-item> declares the required type of the context item when the containing template is called; it can also exist as a child of <xsl:mode> (see Declarations). It can have the following attribute: