我是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,电话)但我只得到两个节点:Eintrag,Eintrag .
有人可以解释一下吗?我以为我的匹配模板匹配“所有节点”?
2 回答
身份模板与使用"for-each"的示例模板之间的区别在于身份模板使用
<xsl:apply-templates/>
来处理其子项 . 这找到了处理每个子节点的最佳匹配模板规则,并且在每种情况下,这又是标识模板,因此处理会向下递归树结构 . 但是在您的示例模板中,您处理所选节点的子节点并输出其名称,但您不会尝试将模板应用于子节点,因此不会进行递归 .identity transform模板与 any 节点匹配(
/
根节点除外) . 它复制匹配的节点并将模板应用于其子节点 .要匹配的第一个节点是根元素 . 从那里开始,处理向下移动到子节点,依此类推,直到整个树被递归处理(假设没有覆盖模板) .
补充:
您的模板只应用一次到根
Telefonliste
元素 . 从那里,your xsl:for-each
指令处理两个子节点Eintrag
节点 . 不进行进一步处理,因为没有指定(没有xsL:apply-templates
指令) .您需要区分
select
表达式和match
模式 .select
表达式选择表达式计算为true的 all 个节点 .另一方面,
match
模式不选择任何内容 . XSLT处理器使用match
模式来查找要应用于当前处理的节点的最佳匹配模板 .通常的顺序是:
xsl:apply-templates
指令选择要处理的节点集 . 对于节点集中的每个节点,处理器从样式表的模板中选择要应用的模板(如果未找到匹配的模板,则从内置的默认模板中选择) . 如果模板包含xsl:apply-templates
指令,则重复该过程 .