XSL模板处理所有后代,而不仅仅是子级

时间:2010-07-20 07:53:18

标签: xslt

鉴于以下XML和XSL转换,我希望输出中包含文本<node/>first的两个second元素。这种期望基于以下推理:

  1. 首先执行带有match="/root"的模板。此模板中的<xsl:apply-templates/>指令将应用最具体的模板for all child nodes
  2. 这些<foo/>子节点将由第二个模板处理。此模板还包含<xsl:apply-templates/>指令,该指令将模板应用于这些节点的子节点。
  3. <foo/>个节点仅包含<bar/>个节点,这些节点与任何模板都不匹配。这意味着不会再处理其他节点。
  4. XML

    <?xml version="1.0" encoding="utf-8"?>
    <?xml-stylesheet type="text/xsl" href="style.xsl"?>
    <root>
      <foo name="first">
        <bar>
          <foo name="nested"/>
        </bar>
      </foo>
      <foo name="second">
        <bar>
          <baz>
            <foo name="nested"/>
          </baz>
        </bar>
      </foo>
    </root>
    

    XSL

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:template match="/root">
        <output>
          <xsl:apply-templates/>
        </output>
      </xsl:template>
      <xsl:template match="foo">
        <node>
          <xsl:value-of select="@name"/>
        </node>
        <xsl:apply-templates/>
      </xsl:template>
    </xsl:stylesheet>
    

    但是,上述转换的实际结果包含四个<node/>元素,其中两个包含文本nested。这意味着第二个模板也应用于最内部的<foo/>节点。但是根据前面提到的步骤3,处理引擎永远不应该到达这些节点。

    我已在多个Web浏览器中测试了转换并使用Notepad ++ XML Tools插件,所有这些都显示“错误”结果。所以我想我错了,但我的推理有什么问题?

2 个答案:

答案 0 :(得分:3)

但是条形节点与模板匹配,它们与内置的“*”模板相匹配,模板传播模板,调用内部条/节点模板

答案 1 :(得分:1)

您的假设是模板匹配是根据嵌套级别完成的。事实并非如此。

<xsl:template match="foo">

这与所有 foo元素匹配,无论其嵌套级别如何,因此在调用apply-templates时,所有foo元素都将使用此模板。

built in template rules也会导致bar个节点匹配。