Reputation: 1678
For example, consider the following XML:
<root>
<level1>
<!--S-->
<level2>bingo!</level2>
</level1>
</root>
And assume we have two templates: match="level2"
and match="level1/level2"
.
When parser reaches the level2
node, how exactly does it determine that current node is matched by both templates, and that it must choose second template because it is more specific? What is formal definition of a "more specific" template?
Upvotes: 3
Views: 257
Reputation: 57189
I agree with FiveO that this is a duplicate question, but then again, you also ask specification what the difference is between foo
and bar/foo
and which one is selected.
Essentially, unless you specify a priority on the xsl:template
declaration, the order in which things are matched is determined by the rules in 5.5 Conflict Resolution for Template Rules for XSLT 1.0, 6.4 Conflict Resolution for Template Rules for XSLT 2.0 and 6.4 Conflict Resolution for Template Rules. These are the formal definitions you asked for.
However, the basic rule is quite simple: the more specific a match, the higher the priority. Except that there is no difference in priority between multiple predicates or deeper paths.
If two templates match that have the same priority, in XSLT 1.0 and 2.0 the processor can either recover (take the last one in declaration order) or signal the error. In 3.0 you can set this behavior declarative with <xsl:mode on-multiple-match="xxx" />
.
A NodeTest (which is your match="level2"
) gets default priority -0.5
and if it has a child axis specifier (which is your match="level1/level2"
) it gets default priority 0
. Higher priority goes first, which is why bar/foo
will match foo
, provided it has a parent bar
. Otherwise it will match foo
.
The basics of these rules have not changed between XSLT versions, they have just been expanded to allow specification of new allowed syntax.
More information is in the linked question.
Update, based on comment:
You ask how this is implemented. I can only speak for our XSLT 3.0 processor, Exselt, and explain it in general lines, because the actual process is rather involved because of many subtleties and optimizations.
NameTest
or KindTest
(see productions of these in the XPath spec)
** Only if it matches, the next (to the left) child axis step is matched, and so on
** If the full path matches, the predicate, if any is evaluated against the current node, this is done later, because it is a more involved process and may require the processor to move away from the current node, which is relatively costly.Upvotes: 4