How XSLT Priority Resolves Template Conflicts
When processing XML documents using XSLT, multiple template rules
often match the same node, creating a conflict. The XSLT processor
resolves these conflicts through a strict hierarchy based on import
precedence, template priority, and document order. By explicitly
defining the priority attribute on an
xsl:template, developers can override default calculation
rules and precisely control which template executes when multiple
patterns match.
The Conflict Resolution Hierarchy
When an XSLT processor evaluates nodes against templates, it selects the winning template using the following order of evaluation:
- Import Precedence: Templates defined in the primary
stylesheet take precedence over templates brought in via
<xsl:import>. - Explicit Priority: If two conflicting templates
have the same import precedence, the processor checks for an explicit
numeric
priorityattribute. The template with the higher numerical value is selected. - Computed Default Priority: If no explicit priority
is set, the processor automatically calculates a default priority based
on the complexity and specificity of the template’s
matchpattern. - Declaration Order: If two matching templates share the exact same precedence and priority, XSLT processors either report a static error or resolve the ambiguity by selecting the template that appears last in the stylesheet.
How the Priority Attribute Works
The priority attribute accepts any real number,
including positive values, negative values, and decimals (e.g.,
priority="2", priority="0.5",
priority="-1").
<!-- Higher priority: this template executes for <item type="special"> -->
<xsl:template match="item[@type='special']" priority="2">
<div class="highlight"><xsl:apply-templates/></div>
</xsl:template>
<!-- Lower priority: this template will be skipped for special items -->
<xsl:template match="item" priority="1">
<div class="standard"><xsl:apply-templates/></div>
</xsl:template>A higher numeric value always takes precedence over a lower one, regardless of where the templates appear in the file or how specific their XPath match patterns are.
Computed Default Priorities
When the priority attribute is omitted, the XSLT
specification assigns a default priority between -0.5 and
+0.5 based on pattern specificity:
- +0.5 (Specific tests and paths): Assigned to
patterns that contain a path or a predicate test, such as
parent/childorelement[@attribute]. - 0 (Named nodes): Assigned to patterns that match a
specific node name or attribute name, such as
title,@id, orprocessing-instruction('target'). - -0.25 (Namespace wildcards): Assigned to patterns
matching any node within a specific namespace, such as
prefix:*or@prefix:*. - -0.5 (Generic wildcards): Assigned to generic node
tests and wildcards with the lowest specificity, such as
*,@*,node(),text(), andcomment().
Best Practices for Managing Conflicts
- Use explicit priorities for intentional overrides:
When creating fallback rules or specialized handlers where default
specificity does not yield the desired result, set
priorityexplicitly. - Keep priority scales manageable: Use small,
integer-based values (such as
1,2,10) rather than arbitrary large numbers to keep stylesheets maintainable. - Combine with import precedence: Use imported stylesheets for broad baseline transformations and explicit priorities within the importing stylesheet to override specific edge cases.