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

如何使用XSLT 1.0移除子元素为空或不存在的XML element节点?

问题需求

需要处理XML文档,当<element>节点的field1和field2子元素**均不存在或内容为空(含空白字符)**时,移除该<element>节点。

输入示例

<root><!-- document -->
  <element><!-- keep -->
    <field1>A</field1>
  </element>
  <element><!-- keep -->
    <field2>B</field2>
  </element>
  <element><!-- delete -->
    <field1/>
  </element>
  <element><!-- delete --></element>
  <element/><!-- delete -->
</root>

当前失效的XSLT 1.0代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
    <xsl:copy-of select="node()"/>
</xsl:template>
<xsl:template match="element">
    <xsl:choose>
        <xsl:when test="field1 or field2">
            <xsl:copy>
                <xsl:copy-of select="node()"/>
            </xsl:copy>
        </xsl:when>
        <xsl:otherwise/>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

问题原因

根模板使用了<xsl:copy-of select="node()"/>,该指令会直接复制整个节点树,完全绕过后续针对element节点的模板匹配逻辑,导致过滤规则无法生效。

解决方案

使用XSLT的身份模板默认复制所有节点,再针对需要过滤的element节点编写匹配模板,仅保留符合条件的节点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <!-- 身份模板:默认复制所有节点和属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 过滤不符合条件的element节点 -->
  <xsl:template match="element[
    (not(field1) or normalize-space(field1) = '') 
    and 
    (not(field2) or normalize-space(field2) = '')
  ]"/>
</xsl:stylesheet>

规则说明

  • normalize-space(field1) = '':同时处理空节点(如<field1/>)、仅含空白字符的节点(如<field1> </field1>)
  • 当element节点的field1和field2都满足「不存在或内容为空/空白」时,该模板匹配后不输出任何内容,即移除该节点
  • 其他element节点会通过身份模板被保留并复制

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:12:45