How Did XSLT 3.0 Enhance Template Modes?

XSLT 3.0 transformed template matching by turning modes from lightweight labels into formal, configurable processing pipelines. Through the introduction of the top-level <xsl:mode> declaration, special mode tokens like #all and #default, and explicit schema-typing controls such as typed="untyped", the specification eliminated extensive boilerplate code, improved modularity in stylesheet packages, and simplified streaming architectures.

Explicit Mode Configuration with xsl:mode

In earlier versions of XSLT, modes were declared implicitly whenever a template specified a mode attribute. XSLT 3.0 introduced the <xsl:mode> declaration, allowing developers to define global behaviors, visibility, and execution strategies for named and unnamed modes:

<xsl:mode name="transform-pass" on-no-match="shallow-copy" streamable="no"/>

This explicit declaration controls several operational aspects:

Targeting Modes with #default

The #default token provides a standardized way to reference the unnamed, default processing mode. This token can be used in the mode attribute of <xsl:template> and <xsl:apply-templates>:

<!-- Matches the element in both the default unnamed mode and a specific named mode -->
<xsl:template match="para" mode="#default summary-pass">
    <p><xsl:apply-templates/></p>
</xsl:template>

Additionally, stylesheets can define module-wide defaults using the default-mode attribute on <xsl:stylesheet>, redirecting un-annotated <xsl:template> and <xsl:apply-templates> instructions to any named mode without manual tag-by-tag updates.

Universal Rule Application with #all

The #all keyword allows a single template rule to apply across all existing modes in the stylesheet:

<xsl:template match="comment() | processing-instruction()" mode="#all"/>

When a template is marked with mode="#all", the XSLT processor copies that rule into every declared or referenced mode. This eliminates the need to duplicate utility rules (such as stripping comments, normalizing text, or emitting debugging signals) across multi-pass transformation pipelines.

Declaring Data Types with typed="untyped"

XSLT 3.0 introduced the typed attribute on <xsl:mode> to declare whether template rules in that mode expect schema-validated or untyped input:

<xsl:mode name="ingest-mode" typed="untyped"/>

Setting typed="untyped" asserts that nodes processed by the mode have not undergone schema validation. This gives the processor static information that all elements and attributes match xs:untyped and xs:untypedAtomic, bypassing type-checking overhead and enabling optimized path navigation and pattern matching.

The Built-in Identity Revolution

Prior to XSLT 3.0, performing an identity transformation with selective overrides required writing an explicit identity template. With XSLT 3.0, a complete identity transform mode requires only a single line:

<xsl:mode on-no-match="shallow-copy"/>

By combining on-no-match="shallow-copy", #default, and #all, developers can write focused stylesheets containing only the rules for nodes that require modification, while the underlying mode infrastructure handles recursive document copying automatically.