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

使用XSLT移除XML空标签(含空白字符的标签除外)

XML移除空标签后残留空行的原因及解决办法

问题场景

需要用XSLT移除XML里**完全无内容(连空白字符都没有)**的空标签,保留包含空白字符的标签,同时不打乱原有格式。

源XML

<inRoot>
    <t1></t1>
    <t2> </t2>
    <t3>World</t3>
</inRoot>

期望输出

<inRoot>
    <t2> </t2>
    <t3>World</t3>
</inRoot>

尝试的XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml"/>
 <xsl:strip-space elements=""/>
    <xsl:template match="/">
        <xsl:apply-templates select="*"/>
    </xsl:template>
    <xsl:template match="*">
            <xsl:if test=".!=''">
                <xsl:copy>
                  <xsl:copy-of select="@*"/>
                  <xsl:apply-templates/>
                </xsl:copy>
            </xsl:if>
    </xsl:template>
</xsl:stylesheet>

实际输出(存在问题)

<inRoot>
    
    <t2> </t2>
    <t3>World</t3>
</inRoot>

空行残留的原因

空行留在那是因为两个核心问题:

  1. 你的模板只处理了元素节点(match="*"),完全没管文本节点。<t1>所在行的缩进空白(比如那行的四个空格+换行)是<inRoot>的子文本节点,当<t1>被移除后,这个空白文本节点就单独留了下来,最终渲染成空行。
  2. <xsl:strip-space elements=""/>的写法无效——它不是全局剥离所有空白,而是仅剥离未指定preserve-space的元素内的空白,这里没指定具体元素,导致<inRoot>下的空白文本节点没被处理。

另外,判断条件.!=''也有漏洞:它检查元素的字符串值,<t2>的字符串值是空格(非空)所以能保留,但<t1>的字符串值是空会被过滤,可它周围的空白文本节点没被清理。


解决办法

要同时处理元素节点和文本节点,确保无用的空白文本节点被清理,同时保留<t2>里的有意义空白。

简洁版XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <!-- 剥离所有元素内的纯空白文本节点 -->
    <xsl:strip-space elements="*"/>
    <!-- 保留包含空白字符的元素内的空白 -->
    <xsl:preserve-space elements="*[text()[normalize-space(.) = '']]"/>
    
    <!-- 直接匹配并移除完全空的元素(无内容、无空白、无子节点) -->
    <xsl:template match="*[normalize-space(.) = '' and not(text())]"/>
    
    <!-- 默认模板:复制所有其他节点(属性、文本、有效元素等) -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

代码说明

  • <xsl:strip-space elements="*"/>:全局剥离所有元素内的纯空白文本节点,包括<inRoot>下原本<t1>所在行的缩进空白。
  • <xsl:preserve-space elements="*[text()[normalize-space(.) = '']]"/>:专门保留那些内部只有空白字符的元素(比如<t2>)里的空白,避免被误删。
  • 匹配规则*[normalize-space(.) = '' and not(text())]:精准匹配完全空的元素——既没有非空白内容,也没有任何文本节点(包括空白),直接跳过不复制,也就是移除这类标签。

这样处理后,<t1>会被彻底移除,同时它所在行的空白也会被清理,不会留下空行,<t2>和<t3>都能按预期保留,格式完全符合要求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:23:13