当相同的XML元素通过不同的XPath匹配两个XSLT模板时,执行哪个模板?为什么?

时间:2009-10-07 14:41:04

标签: xslt

考虑这个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没有。这背后的运作原理是什么?我可以想到三件事:

  1. XPath的特殊性(非常值得怀疑)
  2. XSLT文件中的位置(也值得怀疑)
  3. 模板#1对模板#2的一些先发制人。在执行模板#1期间发生了一些事情,告诉模板#2不执行。

4 个答案:

答案 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>