xsl:apply-templates如何只匹配我定义的模板?

use*_*940 23 xslt

我有几个模板匹配xml文档中的各个节点.如果我只做
<xsl:apply-templates />,它会以某种方式递归输出下面所有节点的文本.我只是想让它递归匹配我定义的任何模板.我怎么做 ?

Mad*_*sen 40

这是因为XSLT中的内置模板.XSLT有几个内置模板,它们说:

  • 将模板应用于元素时,请处理其子元素
  • 将模板应用于文本节点时,请提供其值

总之,这意味着如果您将模板应用于元素但没有该元素的显式模板,则会对其内容进行处理,最终您最终会得到该元素包含的文本.

请阅读完整说明:http://www.dpawson.co.uk/xsl/sect2/defaultrule.html

您可以通过定义自己的模板来覆盖文本节点的默认模板,并使其不执行任何操作.

<xsl:template match="text()" />
Run Code Online (Sandbox Code Playgroud)

  • 如果在 XSLT 2.0 中并使用模板模式,使用 `&lt;xsl:template match="text()" mode="#all" /&gt;` 可能会有所帮助。否则,如果您例如执行 `&lt;xsl:apply-templates mode="foo" /&gt;`,默认文本模板仍将适用。 (2认同)

Dim*_*hev 24

这可能是即使是经验丰富的XSLT程序员经历的最常见问题.

观察到的行为正是XSLT兼容处理器的行为方式.

考虑到:

    <xsl:apply-templates/>

是以下内容的缩写:

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

以及内置模板规则的存在.根据XSLT 1.0规范:

" 5.8内置模板规则

有一个内置模板规则,允许在样式表中的显式模板规则没有成功模式匹配的情况下继续递归处理.此模板规则适用于元素节点和根节点.以下显示了内置模板规则的等效内容:

<xsl:template match="*|/">
  <xsl:apply-templates/>
</xsl:template>

每种模式还有一个内置模板规则,它允许递归处理在样式表中的显式模板规则没有成功模式匹配的情况下以相同模式继续.此模板规则适用于元素节点和根节点.以下显示模式m的内置模板规则的等效项.

<xsl:template match="*|/" mode="m">
  <xsl:apply-templates mode="m"/>
</xsl:template>

还有一个用于文本和属性节点的内置模板规则,用于复制文本:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

用于处理指令和注释的内置模板规则是什么都不做.

<xsl:template match="processing-instruction()|comment()"/>

命名空间节点的内置模板规则也不做任何事情.没有可以匹配命名空间节点的模式; 因此,内置模板规则是应用于命名空间节点的唯一模板规则.

内置模板规则被视为在样式表之前隐式导入,因此导入优先级低于所有其他模板规则.因此,作者可以通过包含显式模板规则来覆盖内置模板规则"

--- XSLT规范结束报价---

因此,如果作者想要完全控制XSLT处理,他们应该覆盖所有内置模板.

例如,如果我们不希望将text()节点复制到输出,我们可以通过以下方式覆盖内置模板来忽略它们:

    <xsl:template match="text()" />