How Does the Mode Attribute Work in XSLT?
The mode attribute in XSLT allows developers to process
the same XML node multiple times in different ways within a single
stylesheet. By assigning explicit modes to
<xsl:template> definitions and matching
<xsl:apply-templates> calls, XSLT can apply distinct
formatting rules to identical source data without creating conflicting
template rules.
Understanding the Problem: Single Match Conflicts
In standard XSLT processing, the XSLT processor selects templates based on pattern priority and specificity. When multiple templates match the exact same node pattern, the processor either takes the one with the highest priority or raises an error due to ambiguity.
Consider a scenario where an XML document contains chapter titles. You might want to format these titles as linked list items in a Table of Contents at the top of the page, while also formatting them as large headings in the main body. Without a mechanism to distinguish context, a single matching template cannot serve both layout purposes cleanly.
How the Mode Attribute Works
The mode attribute acts as a namespace-like tag or state
label. A template defined with a specific mode will only execute when an
xsl:apply-templates instruction explicitly requests that
same mode.
- Declaration: An
<xsl:template>usesmode="mode-name"to declare that it belongs to a specific processing pipeline. - Invocation: An
<xsl:apply-templates>element usesmode="mode-name"to instruct the processor to only match templates tagged with that exact mode. - Default State: Templates and
apply-templatescalls without amodeattribute operate in the default, un-named mode. A modalapply-templatescall will ignore default templates, and standardapply-templatescalls will ignore modal templates.
Practical Implementation Example
Below is a standard pattern demonstrating how mode
enables generating both a summary list and detailed content from the
same source nodes:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/book">
<html>
<body>
<!-- Generate Table of Contents using 'toc' mode -->
<h2>Table of Contents</h2>
<ul>
<xsl:apply-templates select="chapter" mode="toc"/>
</ul>
<!-- Generate Full Content using default mode -->
<div class="content">
<xsl:apply-templates select="chapter"/>
</div>
</body>
</html>
</xsl:template>
<!-- Template for Table of Contents -->
<xsl:template match="chapter" mode="toc">
<li>
<a href="#{generate-id()}">
<xsl:value-of select="title"/>
</a>
</li>
</xsl:template>
<!-- Template for Main Body -->
<xsl:template match="chapter">
<section id="{generate-id()}">
<h1><xsl:value-of select="title"/></h1>
<p><xsl:value-of select="body"/></p>
</section>
</xsl:template>
</xsl:stylesheet>Advanced Features: Built-in Modes and XSLT 2.0+ Enhancements
Modern versions of XSLT introduced additional keywords and controls for mode management:
#default: Explicitly targets or defines templates in the un-named default mode.#current: Inherits whatever mode is currently active in the calling template, making helper templates reusable across different modes.#all(XSLT 2.0+): Allows a single template rule to apply across all modes, useful for utility behaviors like stripping unwanted whitespace or passthrough copying.<xsl:mode>(XSLT 3.0): Allows global configuration of mode behaviors, such as defining fail-safe fallback policies (e.g.,on-no-match="shallow-copy"oron-no-match="fail").
By decoupling template selection from raw node patterns, the
mode attribute provides the structural flexibility needed
for complex multi-view document transformations.