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

如何修改XSLT模板匹配规则移除指定节点的空元素及空父节点

解决指定XML节点的空元素移除问题

需求说明

仅针对section[@desc='a']、section[@desc='b']、remove这三类节点执行以下处理:

  • 移除节点内所有空元素(包含嵌套层级里的空元素)
  • 若处理后该父节点无任何有效子元素,则连同父节点一起移除

示例XML

<?xml version="1.0" encoding="UTF-8"?>
<item>
    <perm desc="item_1">
        <section desc="a">
            <delete></delete>
            <nondelete>a</nondelete>
        </section>
        <section desc="b">
            <delete></delete>
            <nondelete>a</nondelete>
        </section>
        <section desc="c">
            <delete></delete>
            <nondelete>a</nondelete>
        </section>
        <details>
            <firstname desc="Name">John</firstname>
            <lastname desc="Last"></lastname>
            <phone desc="phone"></phone>
        </details>
    </perm>
    <remove>
        <delete></delete>
    </remove>
</item>

原XSLT(存在问题)

原实现会残留空父节点,且无法处理嵌套子元素里的空元素:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="section[@desc='a']|section[@desc='b']|remove/*[not(self::perm)][not(descendant::text()[normalize-space()])]" />

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

</xsl:stylesheet>

预期输出XML

<?xml version="1.0" encoding="UTF-8"?>
<item>
    <perm desc="item_1">
        <section desc="a">
            <nondelete>a</nondelete>
        </section>
        <section desc="b">
            <nondelete>a</nondelete>
        </section>
        <section desc="c">
            <delete></delete>
            <nondelete>a</nondelete>
        </section>
        <details>
            <firstname desc="Name">John</firstname>
            <lastname desc="Last"/>
            <phone desc="phone"/>
        </details>
    </perm>
</item>

修正后的XSLT方案

以下实现可处理嵌套空元素,并在父节点无有效子元素时移除父节点:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<!-- 处理目标节点:section[@desc='a']、section[@desc='b']、remove -->
<xsl:template match="section[@desc='a']|section[@desc='b']|remove">
    <!-- 先处理所有子节点,过滤空元素 -->
    <xsl:variable name="filtered-children">
        <xsl:apply-templates select="node()"/>
    </xsl:variable>
    <!-- 仅当处理后有有效内容时,才复制当前节点 -->
    <xsl:if test="normalize-space($filtered-children) != ''">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:copy-of select="$filtered-children"/>
        </xsl:copy>
    </xsl:if>
</xsl:template>

<!-- 移除所有空元素(适用于目标节点的嵌套子元素) -->
<xsl:template match="*[not(@*) and not(normalize-space()) and not(node())]"/>
</xsl:stylesheet>

嵌套节点测试示例

对于如下嵌套结构:

<section desc="b">
    <child>
        <a>12</a>
        <b></b>
    </child>
    <delete></delete>
    <nondelete>a</nondelete>
</section>

修正后的XSLT会输出:

<section desc="b">
    <child>
        <a>12</a>
    </child>
    <nondelete>a</nondelete>
</section>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:25:08