XSLT apply-templates 的默认选择是什么?

14
身份模板长这样:
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>

<xsl:apply-templates select="@*|node()" /><xsl:apply-templates />相比,是否会选择更多的内容,还是可以将identity模板写成这样?

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

当我执行以下操作时,到底会选择什么?

<xsl:apply-templates />
3个回答

20

<xsl:apply-templates select="@*|node()" /><xsl:apply-templates />相比,是否选择更多的节点或属性?还是说标识模板可以像这样:

<xsl:apply-templates/> 

等同于:

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

这是一个更短的形式:

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

这相当于:

<xsl:apply-templates select="* | text() | comment() | processing-instruction()"/>

从最后一条指令可以看出,你所问的xsl:apply-templates指令并未选择任何属性,因此不能用作以下缩写:

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

@OP:附言:这在http://www.w3.org/TR/xslt#section-Applying-Template-Rules中有定义:“如果没有选择属性,xsl:apply-templates指令将处理当前节点的所有子节点,包括文本节点……”请注意,属性节点不被视为其父元素的子节点。 - LarsH
@LarsH,是的,但有时读者会觉得引用规范是“令人生畏的” :) - Dimitre Novatchev
如果我必须在只引用规范和仅解释其含义之间做出选择,我会选择你的答案(除非我认为规范的影响在这一点上非常容易理解)。然而,在提供有帮助的解释的同时,我认为指向主要材料可以帮助用户“学会如何钓鱼”。这里的OP似乎是一位有成就的程序员,不应该害怕规范。 :-) - LarsH

5
< p >默认的<xsl:apply-templates/>选择器仅包括"node()",不包括属性。


啊,那么就很合理了 :) - Svish

2

apply-templates 的默认选择是 node(),它是 child::node() 的缩写。该 XPath 表达式的评估如下:

  • 首先,从“child”中取出所有节点。这些是当前元素的直接子元素,即其他元素、文本和注释,但不包括属性。
  • 然后,使用“node()”节点测试过滤此节点集。在这种情况下,没有元素被过滤,因为该测试匹配所有内容。

因此,使用<xsl:apply-templates />,将应用子元素的模板,但不会应用属性的模板。对于复制模板而言,这意味着属性不会被复制。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接