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:
- 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. - 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. - 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.
精彩评论