To further complicate how templates are called, it is possible to introduce something called a mode. A mode makes it possible to call a specific function in a specific context. Consider the following XSLT that uses modes:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="elements" mode="embedded"> <xsl:apply-templates mode="embedded"/> Mode Embedded (<xsl:value-of select="text()" />) </xsl:template> <xsl:template match="elements"> <xsl:apply-templates mode="embedded"/> (<xsl:value-of select="text()" />) </xsl:template> <xsl:template match="text()"> </xsl:template> </xsl:stylesheet>
In the example XSLT template, there are two xsl:template instructions with an identical match of elements XML nodes. The way that XSLT matches these nodes is to search for a match without a mode because, by default, XSLT has no modes to match on. Therefore, for the higher-level elements XML nodes without a mode, the xsl:template will be matched. After an elements XML node is matched, the xsl:apply-templates instruction is called with the mode attribute set to embedded. Whenever any matches are attempted, the mode embedded must also be present. In this example XSLT, this is the case because there is an elements match with a mode of Embedded. Executing the XSLT document on the original XML document generates the following output:
<?xml version=”1.0” encoding=”UTF-8”?>Hello (Hello) Embedded Mode Embedded (Embedded) ()
Everything seems okay in the output except for one extra piece of information. The Embedded text on the third line of the output is out of place. There should be a bracket around the text. This text is generated because the xsl:template with match elements and mode of embedded has an embedded xsl:apply-templates with a mode of embedded. If you inspect the original XML document, you see the elements XML node with an identifier attribute of 3 has an embedded text node. Because a switch of modes has been defined, the xsl:template instruction with a match of text() has no mode defined and, therefore, is not called. To solve this problem, consider the built-in template xsl:template definition and modify the original XSLT to the following:
<xsl:template match=”text()” mode=”?”> </xsl:template>
The mode definition set to the question mark indicates that any particular mode is okay when attempting to match this node.