为什么没有选择更好的匹配模板?

时间:2015-01-31 11:09:40

标签: .net xslt xslt-1.0

我有以下xml:

<root xmlns:s="http://example.com/schema">
  <foo>
     <s:bars>
       <s:bar name="normal">bar101</s:bar>
       <s:bar name="special">Foobar</s:bar>
       <s:bar name="super">FuBar</s:bar>
     </s:bars>
  </foo>
</root>

我使用以下xslt模板输出bar元素:

  <xsl:template match="root">
    <foos>
      <xsl:apply-templates select="foo/s:bars"/>
    </foos>
  </xsl:template>

  <xsl:template match="s:bars/s:bar[@name='special' or @name='super']">
    <xsl:element name="{@name}">
      <xsl:text>special value:</xsl:text>
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="s:bars/s:bar">
    <xsl:element name="{@name}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

奇怪的是,当使用.Net XSLT处理器时,它会输出以下xml:

<foos>
  <normal>bar101</normal>
  <special>Foobar</special>
  <super>FuBar</super>
</foos>

显然没有使用s:bars/s:bar[@name='special' or @name='super']的模板。我期待以下输出:

<foos>
  <normal>bar101</normal>
  <special>special value:Foobar</special>
  <super>special value:FuBar</super>
</foos>

我尝试添加额外的模板来选择bars

  <xsl:template match="s:bars">
    <xsl:comment>bars</xsl:comment>
    <xsl:apply-templates />
  </xsl:template>

但这并没有改变结果(但确实将<!--bars-->添加到结果中,因此模板被调用。)

我似乎期待与template rules不同的东西或误解它们。是否应该在元素的匹配项上选择元素 AND 属性匹配?

如何更改我的XSLT模板以使用.Net XSLT处理器实现获得所需的输出?

1 个答案:

答案 0 :(得分:2)

两个模板具有相同的优先级0.5(请参阅http://www.w3.org/TR/xslt#conflict),因此XSLT处理器可以报告错误或采用最后一个错误。如果您没有收到错误,那么您的XSLT处理器已采用最后一个匹配的模板规则。因此,要么更改订单,要么在您想要首选的优先级上设置明确的优先级(例如<xsl:template match="s:bars/s:bar[@name='special' or @name='super']" priority="5">)。