本地化后如何用XSLT移除所有含/不含属性的空XML元素?
这是个很典型的XML后处理场景,我给你准备了两种XSLT方案,能精准移除所有**无有效内容(包括仅含空白文本)**的空元素——不管元素本身有没有属性:
XSLT 1.0 版本(兼容性最强)
这个版本适用于所有支持XSLT 1.0的处理器(比如Xalan、libxslt等):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配并移除空元素:无任何非空白文本,也没有子元素 --> <xsl:template match="*[not(normalize-space()) and not(*)]"/> </xsl:stylesheet>
代码说明:
- 身份模板是XSLT的基础模板,负责原样复制所有不需要特殊处理的节点(文本、属性、非空元素等),保证你的XML结构中有用的部分完全保留。
- 第二个模板专门定位要删除的空元素:
*匹配所有XML元素not(normalize-space())确保元素的所有文本内容(包括子节点里的文本)去掉首尾空白后为空(纯空白的文本也会被判定为空)not(*)确保元素没有任何子元素
同时满足这两个条件的元素,模板会输出空内容,相当于直接移除它们。
XSLT 2.0+ 版本(更简洁)
如果你的处理器支持XSLT 2.0或更高版本(比如Saxon),可以用更简洁的写法:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 替代身份模板:默认浅拷贝所有节点 --> <xsl:mode on-no-match="shallow-copy"/> <!-- 移除空元素的逻辑和1.0版本完全一致 --> <xsl:template match="*[not(normalize-space()) and not(*)]"/> </xsl:stylesheet>
特殊情况处理
如果有某些特定标签即使是空的也需要保留,可以修改删除模板的匹配条件来排除它们。比如要保留<required-empty-tag>:
<!-- 修改后的删除模板 --> <xsl:template match="*[ not(normalize-space()) and not(*) and not(local-name()='required-empty-tag') ]"/>
如果标签带命名空间,记得提前在样式表声明命名空间,再用self::前缀:标签名来排除。
测试方式
你可以用本地的XSLT处理器(比如Saxon CLI、Xalan)或者离线工具,把你的XML文件和这个样式表一起处理,就能得到清理后的结果。
内容的提问来源于stack exchange,提问作者Ilia Shifrin
相关产品推荐
相关产品推荐

