We'll now look at the template rules used to format the section headers. These all have the same structure, and they reuse components we have already seen: the named anchor template that generates the target of a hyperlink, and the divnum mode that produces the section number for any given section. Here are the first two:
<xsl:template match="div1/head"> <h2> <xsl:call-template name="anchor"> <xsl:with-param name="conditional" select="0"/> <xsl:with-param name="node" select=".."/> </xsl:call-template> <xsl:apply-templates select=".." mode="divnum"/> <xsl:apply-templates/> </h2> </xsl:template> <xsl:template match="div2/head"> <h3> <xsl:call-template name="anchor"> <xsl:with-param name="conditional" select="0"/> <xsl:with-param name="node" select=".."/> </xsl:call-template> <xsl:apply-templates select=".." mode="divnum"/> <xsl:apply-templates/> </h3> </xsl:template>
It would be entirely possible to use a single generic template by replacing the literal result element < h N > with the construct:
<xsl:element name="{replace(name(..), 'div', 'h')}">
This uses the XPath 2.0 replace() function, but the same logic could be written almost as easily by using XPath 1.0 functions such as concat() and substring-after() . Another way to avoid repetition of code between these templates would be to write separate template rules at the top level, and call a common component to produce the inner content:
<xsl:template match="div1/head"> <h2> <xsl:apply-templates select="." mode="head"/> </h2> </xsl:template> <xsl:template match="div2/head"> <h3> <xsl:apply-templates select="." mode="head"/> </h3> </xsl:template> <xsl:template match="head" mode="head"> <xsl:call-template name="anchor"> <xsl:with-param name="conditional" select="0"/> <xsl:with-param name="node" select=".."/> </xsl:call-template> <xsl:apply-templates select=".." mode="divnum"/> <xsl:apply-templates/> </xsl:template>
Yet another approach would be for the common template rule to be invoked using <xsl: next -match/> rather than by using a separate mode.