使用xsl:apply-templates理解xsl:copy(XSLT 2.0)

时间:2015-11-13 17:06:32

标签: xml xslt

以下三个模板之间有什么区别?

<xsl:template match="food">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

<xsl:template match="food">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
</xsl:copy>
</xsl:template>

<xsl:template match="food">
<xsl:copy>
</xsl:copy>
<xsl:apply-templates/>
</xsl:template>

我的猜测是第一个和第二个是相同的。但是第三个呢?

2 个答案:

答案 0 :(得分:2)

<xsl:template match="food">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>

复制food元素,然后将模板应用于该元素的子节点(子元素,注释和文本节点),将结果放在复制的元素中。 对原始food元素所具有的任何属性执行任何操作。

<xsl:template match="food">
<xsl:copy>
<xsl:apply-templates select="@* | node()">
</xsl:copy>
</xsl:template>

如上所述,但是将模板应用于food元素的属性及其子元素。这是否具有任何可观察的效果取决于是否存在与这些属性节点匹配的模板以及这些模板的作用。如果您有一般身份模板(见下文),那么复制的food元素最终将具有与原始模板相同的属性。

<xsl:template match="food">
<xsl:copy>
</xsl:copy>
<xsl:apply-templates/>
</xsl:template>

与第一种情况一样,但是在(空)复制的food元素之后将模板应用于子项而不是在其中。

通常,您会希望看到此类模板以及一般的“身份”模板

<xsl:template match="@*|node()">
  <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>

复制所有未更改的内容,除非更多特定模板覆盖此行为

答案 1 :(得分:1)

  

我的猜测是第一个和第二个相同。

不,他们不一样。第一个不将模板应用于属性。这两个是相同的:

<xsl:apply-templates>

<xsl:apply-templates select="node()">
  

但是第三个呢?

第三个模板在复制的节点之外应用模板,导致层次结构扁平化:儿童将成为兄弟姐妹。