How Does XSLT Resolve Conflicting Match Rules?

In XSLT, multiple template rules can often match the same node in a source document, creating potential ambiguity during transformation. The XSLT processor resolves these conflicts through a strict, deterministic resolution pipeline based on import precedence, template priority, and document declaration order. Understanding this hierarchy allows developers to cleanly override styling rules, modularize stylesheets, and write maintainable XML transformations without relying on brittle workarounds.

The Three-Stage Conflict Resolution Model

When an <xsl:apply-templates> instruction executes on a specific node, the processor identifies all template rules whose match pattern matches that node and shares the appropriate mode. To select the winning template, the processor applies three criteria in a strict cascading order:

  1. Import Precedence: Higher import precedence always beats lower import precedence.
  2. Template Priority: If two templates share the same import precedence, the processor evaluates their numeric priorities.
  3. Document Order: If multiple templates have identical import precedence and identical priority, the last declaration in document order wins (or the processor raises an error, depending on the XSLT version and implementation settings).

Understanding Import Precedence

Import precedence establishes a baseline hierarchy between stylesheets included via <xsl:import>. It enables a parent stylesheet to import external libraries and systematically override specific templates while keeping others intact.

The rules governing import precedence are based on a post-order traversal of the import tree:

Template Priority Calculations

If two matching templates share the same import precedence, the processor moves to step two: evaluating priority. Developers can assign an explicit priority using the priority attribute on <xsl:template> (for example, priority="2").

When no explicit priority is provided, XSLT automatically calculates a default priority based on pattern specificity:

Templates with patterns separated by the union operator | are evaluated as separate individual rules, each receiving its own computed default priority.

Document Order Resolution and Overrides

If both import precedence and priority are identical, the processor relies on declaration order within the stylesheet. In standard XSLT processing, the template that appears last in the physical stylesheet document is selected.

While relying on document order is valid, explicitly defining the priority attribute or structuring stylesheets using <xsl:import> provides clearer intent and reduces subtle bugs during large refactoring tasks.

Invoking Overridden Rules with xsl:apply-imports

Import precedence does not merely silence lower-precedence rules; it enables controlled inheritance. Within a winning template, developers can invoke <xsl:apply-imports> (or <xsl:next-match> in XSLT 2.0 and later).

This instruction passes execution directly to the next matching template in the import hierarchy, allowing the high-precedence template to wrap existing transformation logic with additional markup rather than duplicating it entirely.