MENU
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><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><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
- use = "required" | "optional" | "prohibited"