Consider this XML:
<people>
<person>
<firstName>Deane</firstName>
<lastName>Barker</lastName>
</person>
</people>
What if two XSLT templates match an element through different XPaths? I know that if the "match" element on two templates is identical (which should never happen, I don't think), the last template will fire.
However, consider this XSL:
<xsl:template match="person/firstName">
Template #1
</x开发者_如何学编程sl:template>
<xsl:template match="firstName">
Template #2
</xsl:template>
The "firstName" element will match on either of these templates -- the first one as a child of "person" and the second one standalone.
I have tested this, and Template #1 executes, while Template #2 does not. What is the operative principle behind this? I can think of three things:
- Specificity of XPath (highly doubtful)
- Location in the XSLT file (also doubtful)
- Some pre-emption of Template #2 by Template #1. Something happens during the execution of Template #1 that tells Template #2 not to execute.
Your first point is actually correct, there is a defined order described in https://www.w3.org/TR/1999/REC-xslt-19991116#conflict. According to the spec person/firstName
has a priority of 0 while firstName
has a priority of -0.5. You can also specify the priority yourself using the priority
attribute on xsl:template
.
I know that if the "match" element on two templates is identical (which should never happen, I don't think)
This can happen but would not be much point doing this and having two matching templates.
From the spec:
It is an error if this leaves more than one matching template rule. An XSLT processor may signal the error; if it does not signal the error, it must recover by choosing, from amongst the matching template rules that are left, the one that occurs last in the stylesheet.
So in other words you may get an error or it will just use the last template in your XSLT depending on how the processor your are using has been written to handle this situation.
Note that the value of the match
attribute is not an XPath expression (though it uses a subset of XPath syntax). It's an XSLT pattern. Absent explicit priority
attributes, the choice comes down to which pattern has the highest default priority:
person/firstName
has a default priority of .5
firstName
has a default priority of 0
Thus, person/firstName
wins.
A complete explanation of how conflict resolution works can be found here (although I recommend you study the entire chapter, "How XSLT Works"): Conflict Resolution for Template Rules
Consider this with the context in mind. The first one matches, and changes the context n (so the second does not match). The context is set to AFTER the first one is selected and processed so the visible element from that context no longer contains "firstname". IF you want both to execute, then you can call them instead so that the context changes back to the top.
<xsl:template match="people">
<xsl:apply-templates select="person/firstname"/>
<xsl:apply-templates select="firstname"/>
</xsl:template>
精彩评论