XSLT身份转换

时间:2017-07-04 20:19:33

标签: xml xslt recursion

我是XSLT的新手,并且遇到了有关身份转换的技术问题。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

这是一个经常发布的示例,但我从未发现有关详细程序序列的内容。我经常读到它递归地工作。但我不确定详细的过程。 模板匹配所有属性节点和除根节点之外的所有其他节点的并集。然后xsl:copy复制当前的contextnode(没有for-each?!)(应该是文档中的第一个),并使用相同的节点选择再次应用模板。这将完成,直到处理完所有节点?

我想知道程序流程在身份构建中的作用。

== FOLLOW-UP ==

好的,谢谢你的回答。我大致知道XSLT的处理模型。请查看以下内容。我定义了一个模板,它应该产生一组所有节点(根节点除外)。然后我想看看那组节点中有什么。为此,我使用for-each并选择当前上下文节点的名称。

<?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="@* | node()">
    <xsl:for-each select="node()">
        <xsl:value-of select="name()" />
    </xsl:for-each>
</xsl:template>

</xsl:transform>

输入xml:

<Telefonliste>
    <Eintrag>
        <name>Peter</name>
        <nachname>Pan</nachname>
        <Tel>12345</Tel>
    </Eintrag>
    <Eintrag>
        <name>Max</name>
        <nachname>Mustermann</nachname>
        <Tel>98765</Tel>
    </Eintrag>
</Telefonliste>

我希望,我得到了9个节点。 (Telefonliste,Eintrag,名字,nachname,Tel,Eintrag,名字,nachname,Tel)但我只收到两个节点:Eintrag,Eintrag。

有人可以解释一下吗?我以为我的匹配模板匹配“所有节点”?

2 个答案:

答案 0 :(得分:3)

identity transform模板与任何节点(/根节点除外)匹配。它复制匹配的节点并将模板应用于其子节点。

要匹配的第一个节点是根元素。从那里开始,处理向下移动到子节点,依此类推,直到整个树被递归处理(假设没有覆盖模板)。

加了:

  

我希望,我得到了9个节点。 (Telefonliste,Eintrag,名字,   nachname,Tel,Eintrag,name,nachname,Tel)但我只得到两个节点   回来:Eintrag,Eintrag。

您的模板只应用一次到根Telefonliste元素。从那里,your xsl:for-each指令处理两个子Eintrag节点。没有进一步的处理,因为没有指定(你没有xsL:apply-templates指令)。

  

我解释了匹配规则,它匹配其中的所有节点   XML树。我的论文(来自大学)到处都是下划线,就是这样   查询返回一组节点,所以我认为它收集了每个节点   树。

您需要区分select表达式和match模式。

  • select表达式选择表达式的所有节点 评估为真。

  • 另一方面,match模式不会选择任何内容。 XSLT处理器使用match模式来查找要应用于当前处理的节点的最佳匹配模板。

通常的顺序是:xsl:apply-templates指令选择要处理的节点集。对于节点集中的每个节点,处理器从样式表模板中选择要应用的模板(如果未找到匹配的模板,则从内置的默认模板中选择)。如果模板包含xsl:apply-templates指令,则重复该过程。

答案 1 :(得分:3)

使用&#34; for-each&#34;身份模板和示例模板之间的差异是身份模板使用<xsl:apply-templates/>来处理其子项。这找到了处理每个子节点的最佳匹配模板规则,并且在每种情况下,这又是标识模板,因此处理会向下递归树结构。但是在您的示例模板中,您处理所选节点的子节点并输出其名称,但您不会尝试将模板应用于子节点,因此没有递归。