开发者

XSL template processes all descendants, not just children

Given the following XML and XSL transformation, I'd expect two <node/> elements in the output containing the texts first and second. This expectation is based on the following reasoning:

  1. The template with match="/root" will execute first. The <xsl:apply-templates/> instruction in this template will apply the most specific templates for all child nodes.
  2. These <foo/> child nodes will be processed by the second template. This template also contains the <xsl:apply-templates/> instruction, which applies templates to the child nodes of these nodes.
  3. The <foo/> nodes only contain <bar/> nodes, which don't match any template. This implies that no further nodes will be processed.

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>

However, the actual result of the above transformation contains four <node/> elements, of which two contain the text nested. This means that the second template is also applied to the most inner <foo/> nodes. But according to the aforementioned step 3, the processing engine should never reach these nodes.

I have tested the transformation in multiple web browsers and using the Notepad++ XML Tools plug-in, and all of them show the "wrong" result. So I guess I'm wrong here, but what's wrong with my reasoni开发者_Go百科ng?


But the bar nodes do match a template, they match the built in "*" template, which propagates the templates, calling the inner bar/node template


Your assumption is that template matching is done according to nesting levels. This is not the case.

<xsl:template match="foo">

This matches all foo elements, whatever their nesting level, so when calling apply-templates, all foo elements will use this template.

The built in template rules will also cause the bar nodes to be matched.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜