You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何在XSLT中使用mode属性会输出整个XML原始文本?

XSLT mode与name模板输出差异问题解析

问题本质:mode和name的核心功能完全不同

你误以为name和mode功能相近,其实两者定位完全不一样:

  • name属性:只是给模板起个标识名,方便用<xsl:call-template>直接调用,但它不改变模板的匹配逻辑——只要节点符合match规则,处理器在常规(无指定mode)的模板处理流程中,依然会选中这个模板。你用name="xyz"时,<Parent>节点被匹配到该模板,所以输出预期的结构。
  • mode属性:是给模板标记一个“模式”,只有当你通过<xsl:apply-templates mode="xyz">主动调用时,这个模板才会生效。如果没有触发对应模式的调用,处理器会执行XSLT的内置默认模板,这就是你看到原始文本的原因。

为什么mode模板会输出原始文本?

你的mode="xyz"模板没有被触发,因为处理器默认是按“无模式”的方式遍历节点:

  1. 处理器从根节点开始,找不到匹配根节点的自定义模板,就用默认模板处理根节点的子节点(也就是<Parent>)
  2. 处理<Parent>时,因为没有无模式的自定义模板(你的模板只属于xyz模式),所以再次用默认模板处理<Parent>的子节点:<ParentCon>、<Child>
  3. 默认模板处理元素节点时,会递归处理其所有子节点;处理文本节点时,直接输出文本内容。最终所有文本节点(Parent Content、Child Content、Some Grandchild Content)被输出,就得到了你看到的无标记原始文本。

解决方案:让mode模板生效

要让带mode的模板正常工作,需要显式在主模板中触发对应模式的模板调用:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 处理根节点的主模板,触发mode=xyz的模板 -->
  <xsl:template match="/">
    <xsl:apply-templates select="Parent" mode="xyz"/>
  </xsl:template>

  <xsl:template match="Parent" mode="xyz">
    <ExportParent>
      <ExportChild/>
    </ExportParent>
  </xsl:template>
</xsl:stylesheet>

如果希望模板同时支持无模式和指定模式调用(XSLT 2.0及以上版本可用),可以给mode设置多个值:

<xsl:template match="Parent" mode="#default xyz">
  <ExportParent>
    <ExportChild/>
  </ExportParent>
</xsl:template>

这样无论是否指定mode,<Parent>节点都会匹配到这个模板,输出预期结果。


内容的提问来源于stack exchange,提问作者Dragyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 20:55:18