How Does XSLT Compute Default Template Priority?
When an XSLT template rule does not include an explicit
priority attribute, the XSLT processor automatically
assigns a default priority based on the structural specificity of its
match pattern. This built-in resolution mechanism assigns numeric
scores—typically ranging from -0.5 to +0.5—to ensure more specific
patterns (such as exact qualified names or expressions with predicates)
override general wildcard or node-type selectors. Understanding these
exact calculation rules prevents unexpected template collisions during
document transformations.
The Priority Calculation Rules
The W3C XSLT specification defines the default priority computation
based on the syntax of the pattern. When a pattern consists of multiple
alternatives separated by the union operator (|), each
branch is evaluated separately as if each had its own distinct template
rule with its own computed priority.
For single-pattern steps, the processor applies four standard numeric tiers:
- Priority +0.5 (Highest Default Specificity):
Assigned to any pattern that contains a predicate (e.g.,
item[@active='true']), matches multiple path steps (e.g.,section/para), or matches an ID/key lookup function (id('main')orkey('items', @id)). - Priority 0.0 (Specific Name Matches): Assigned to
patterns that match a specific element or attribute name, or a
processing-instruction with a specific target name. Examples include
para,@id, andprocessing-instruction('php'). - Priority -0.25 (Namespace Wildcards): Assigned to
patterns of the form
prefix:*or@prefix:*, matching any element or attribute within a specific namespace. - Priority -0.5 (Most Generic Match): Assigned to
generic node-type tests and unrestricted wildcards. Examples include
*,@*,node(),text(),comment(), and bareprocessing-instruction().
Conflict Resolution and Overrides
If multiple templates match a given node with the same default priority, the processor follows strict conflict resolution rules:
- Explicit Priority: An author can override the
default priority by adding the
priorityattribute (e.g.,<xsl:template match="para" priority="2">). Any explicit numerical priority takes precedence over default calculations. - Import Precedence: Templates in importing stylesheets always take precedence over templates in imported stylesheets, regardless of the calculated default priority.
- Declaration Order: If two matching templates share the exact same import precedence and calculated priority, the processor either raises an error or chooses the template that appears last in the stylesheet declaration order.