How Do Default Template Rules Behave in XSLT?

In XSLT processing, when the transformation engine encounters a node that lacks an explicit template rule, it automatically executes a built-in default template rule. Rather than throwing an error or halting execution, these built-in rules define standard fallback actions that recursively traverse element hierarchies and output text content by default. Understanding how these rules treat different node types is critical for debugging unexpected text leaks and structuring clean stylesheet transformations.

The Recursive Traversal of Elements and Root Nodes

For the document root node (/) and all element nodes (*), the default template rule instructs the processor to continue traversing down the XML tree. The built-in rule behaves conceptually as follows:

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

When an element has no matching custom template, the processor does not construct any markup or output directly. Instead, it applies templates to all immediate children of that element, including child elements and text nodes. This recursive descent continues through the entire XML hierarchy until the processor reaches leaf nodes or encounters an explicit template rule matching a child element.

Text Nodes and Attribute Values

When traversal reaches text nodes or attributes that do not have an explicit template definition, the default rule outputs their string values directly into the result stream. The conceptual rule operates like this:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

This behavior explains a common pitfall in XSLT development: if a developer writes an empty stylesheet or fails to account for unwanted elements, all text content across the entire XML source document is concatenated and printed into the output document. Because attribute nodes are not visited by default child traversal unless explicitly selected via <xsl:apply-templates select="@*"/>, the attribute rule only triggers when attribute selection is active.

Comments and Processing Instructions

Comments and processing instructions are safely ignored when no explicit template matches them. Their built-in template rule is empty:

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

When the processor encounters these nodes during traversal, it discards them without generating output or descending further.

Overriding the Default Behavior

Developers can override these built-in template rules at any level of the stylesheet. To suppress the automatic output of text content, an empty template matching all text nodes can be declared:

<xsl:template match="text()"/>

Alternatively, targeting specific container elements with empty template matches prevents the processor from recursively evaluating child nodes altogether, pruning unwanted branches of the input XML tree before the text rule is reached.