考虑这个XML:
<people>
<person>
<firstName>Deane</firstName>
<lastName>Barker</lastName>
</person>
</people>
如果两个XSLT模板通过不同的XPath 匹配元素,该怎么办?我知道如果两个模板上的“匹配”元素是相同的(这不应该发生,我不认为), last 模板将会触发。
但是,请考虑这个XSL:
<xsl:template match="person/firstName">
Template #1
</xsl:template>
<xsl:template match="firstName">
Template #2
</xsl:template>
“firstName”元素将匹配这些模板中的任何一个 - 第一个作为“person”的子元素,第二个元素是独立的。
我测试了这个,模板#1执行,而模板#2没有。这背后的运作原理是什么?我可以想到三件事:
答案 0 :(得分:8)
您的第一点实际上是正确的,https://www.w3.org/TR/1999/REC-xslt-19991116#conflict中描述了定义的顺序。根据规范person/firstName
的优先级为0,而firstName
的优先级为-0.5。您还可以使用priority
上的xsl:template
属性自行指定优先级。
答案 1 :(得分:3)
我知道如果“匹配”元素就可以了 两个模板是相同的(其中 永远不应该发生,我不认为)
这可能会发生,但这样做并没有多大意义,并且有两个匹配的模板。
来自规范:
如果这样做会有更多错误,那就错了 比一个匹配的模板规则。一个 XSLT处理器可能会发出错误信号; 如果它没有发出错误的信号,那就是 必须通过从中选择来恢复 匹配的模板规则 离开,最后出现的那个 样式表。
因此换句话说,您可能会收到错误,或者只是使用XSLT中的最后一个模板,具体取决于您使用的处理器是如何处理这种情况的。
答案 2 :(得分:2)
请注意,match
属性的值是而不是 XPath表达式(尽管它使用XPath语法的子集)。这是一个XSLT 模式。如果缺少明确的priority
属性,则选择归结为哪个模式具有最高的默认优先级:
person/firstName
的默认优先级为 .5
firstName
的默认优先级为 0
因此,person/firstName
获胜。
可以在此处找到有关冲突解决方式如何工作的完整说明(尽管我建议您研究整个章节“XSLT如何工作”):Conflict Resolution for Template Rules
答案 3 :(得分:0)
考虑到上下文,请考虑这一点。第一个匹配,并更改上下文n(因此第二个不匹配)。上下文设置为选择并处理第一个上下文后,该上下文中的可见元素不再包含“firstname”。 如果你想要两者都执行,那么你可以调用它们,以便上下文变回顶部。
<xsl:template match="people">
<xsl:apply-templates select="person/firstname"/>
<xsl:apply-templates select="firstname"/>
</xsl:template>