如何使用XSLT移除XML默认命名空间及目标命名空间?
移除XML中的默认命名空间和目标命名空间
我有一个包含默认命名空间xmlns="http://www.xxxx.com/xyz"和目标命名空间xmlns:tns="http://www.xxxx.com/xyz"的XML文件,需要将两者完全移除。示例XML如下:
<?xml version="1.0" encoding="UTF-8" ?> <Root xmlns:tns="http://www.xxxx.com/xyz" xmlns="http://www.xxxx.com/xyz"> <Header type="XXXX" purpose="Original" xmlns=""> <ID>XXXXXX</ID> </Header> </Root>
我尝试了以下XSLT代码,但无法移除根元素上的默认命名空间:
<xsl:template match="*"> <!-- remove element prefix --> <xsl:element name="{local-name()}"> <!-- process attributes --> <xsl:for-each select="@*"> <!-- remove attribute prefix --> <xsl:attribute name="{local-name()}"> <xsl:value-of select="."/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates/> </xsl:element> </xsl:template>
解决方案
要彻底移除所有命名空间(包括默认命名空间),需要在创建新元素时显式指定空命名空间,同时直接移除所有命名空间声明属性。修改后的XSLT代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 匹配所有元素,创建不带命名空间的新元素 --> <xsl:template match="*"> <xsl:element name="{local-name()}" namespace=""> <!-- 复制所有非命名空间属性 --> <xsl:copy-of select="@*[not(namespace-uri())]"/> <!-- 递归处理子节点 --> <xsl:apply-templates/> </xsl:element> </xsl:template> <!-- 匹配并移除所有命名空间声明属性(xmlns和xmlns:*) --> <xsl:template match="@*[starts-with(name(), 'xmlns')]"/> <!-- 保留文本、注释、处理指令等非元素节点 --> <xsl:template match="text()|comment()|processing-instruction()"> <xsl:copy/> </xsl:template> </xsl:stylesheet>
关键说明
- 显式指定空命名空间:原代码中
<xsl:element>未指定namespace属性,会自动继承当前节点的默认命名空间,导致新元素仍带有原命名空间。显式设置namespace=""可以强制新元素属于空命名空间。 - 移除命名空间属性:新增的模板直接匹配所有以
xmlns开头的属性,不做任何输出,彻底移除所有命名空间声明(包括默认命名空间和tns命名空间)。 - 简化属性处理:用
<xsl:copy-of>直接复制非命名空间属性,替代原有的循环处理,代码更简洁高效。
处理后输出结果
<?xml version="1.0" encoding="UTF-8"?> <Root> <Header type="XXXX" purpose="Original"> <ID>XXXXXX</ID> </Header> </Root>
内容的提问来源于stack exchange,提问作者Abhijit
相关产品推荐
相关产品推荐

