我对XSLT转换的程序流程提出了疑问。我有以下XML:
<Telefonliste>
<Eintrag att="1">
<name>Peter</name>
<nachname>Pan</nachname>
<Tel>12345</Tel>
</Eintrag>
<Eintrag>
<name>Max</name>
<nachname>Mustermann</nachname>
<Tel>98765</Tel>
</Eintrag>
</Telefonliste>
还有一个xsl文件A:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
Root node
<xsl:apply-templates />
Root node
</xsl:template>
<xsl:template match="node() | @*" >
<xsl:text>Test</xsl:text>
</xsl:template>
</xsl:transform>
还有一个xsl文件B:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/">
Root node
<xsl:apply-templates />
Root node
</xsl:template>
<xsl:template match="node() | @*" >
<xsl:value-of select="self::node()" />
</xsl:template>
</xsl:transform>
A的输出是:
Root node
Test
Root node
这正是我对这种转变的建议。首先调用根模板,打印&#34;根节点&#34;然后将模板应用于child :: node()(apply-templates子句中没有select)。然后它调用第二个模板打印一次&#34;测试&#34;。然后根节点的模板再次打印&#34;根节点&#34;然后转换完成。
如果我运行转换B,我会得到以下输出:
Root node
Peter
Pan
12345
Max
Mustermann
98765
Root node
打印&#34;根节点&#34;这里很清楚。但为什么die会打印所有子节点值?我无法理解,没有循环。我只期望一个值,即当前上下文节点的值......
有人可以解释一下吗?
答案 0 :(得分:0)
考虑以下样式表:
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="/Telefonliste">
Root node
<xsl:value-of select="self::node()" />
Root node
</xsl:template>
</xsl:transform>
应用于您的输入,结果将与转换B中的结果相同。
原因是xsl:value-of
指令返回所选节点的C# library for .NET Core and .NET Framework - 此字符串值包括所有后代文本节点。
答案 1 :(得分:0)
XSLT处理器从Document Node(/)开始读取XML树。对于两个样式表(A和B),执行的第一个模板将是匹配/的模板。 / 的模板将输出文本根节点,并将对文档节点(/)的所有子项执行模板(xsl:appy-templates)。 XML的文档节点有一个子元素 Telephonist 。
您的样式表A和B没有完全匹配 Telefonliste 的模板,因此匹配任何节点(node()| @ *)的模板将用于元素 Telefonliste
对于样式表node()| @ *的模板将生成输出 Test 。 XSLT处理器将返回文档节点 / 的模板,以输出第二个根节点。
node()| @ *的样式表B模板将输出元素 Telefonliste 中的所有PCData与排除属性的深度无关。