XSLT1.0中xsl:copy-of冗余命名空间处理及前缀复用问题
XSLT1.0 移除冗余命名空间并复用根节点前缀的解决方案
环境信息
- .NET Core 7 + msxsl
- XSLT 1.0
问题背景
此前尝试用exclude-result-prefixes属性排除foo命名空间,但使用xsl:copy-of复制节点时,foo命名空间仍会保留。改用通用节点复制模板后,foo命名空间虽被成功移除,但原本属于kookerella命名空间的子元素(如<kookerella:wibble>)会变成默认命名空间声明形式(例如<wibble xmlns="http://example.com/kookerella">),无法复用根节点<kookerella:root>已定义的前缀,导致客户因格式不符合预期拒绝技术上有效的输出结果。
解决方案
核心思路是通过显式绑定命名空间前缀+定向节点处理,既移除冗余的foo命名空间,又确保kookerella命名空间下的子元素复用根节点已声明的前缀:
完整XSLT代码示例
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kookerella="http://example.com/kookerella" <!-- 显式绑定目标命名空间前缀 --> xmlns:foo="http://example.com/foo" exclude-result-prefixes="foo"> <!-- 标记排除foo命名空间 --> <!-- 匹配根节点,保留kookerella前缀的命名空间声明 --> <xsl:template match="/kookerella:root"> <kookerella:root> <xsl:apply-templates select="@* | node()"/> </kookerella:root> </xsl:template> <!-- 复制kookerella命名空间下的元素,强制复用前缀 --> <xsl:template match="kookerella:*"> <xsl:element name="kookerella:{local-name()}" namespace="http://example.com/kookerella"> <xsl:apply-templates select="@* | node()"/> </xsl:element> </xsl:template> <!-- 直接跳过foo命名空间的所有节点和属性 --> <xsl:template match="foo:* | @foo:*"/> <!-- 复制其他非命名空间相关的节点(文本、注释、属性等) --> <xsl:template match="@* | text() | comment() | processing-instruction()"> <xsl:copy/> </xsl:template> </xsl:stylesheet>
关键要点说明
- 显式绑定前缀:必须在XSLT根节点显式声明kookerella命名空间并绑定前缀,msxsl会在输出根节点保留该前缀声明,子元素可直接复用,避免生成默认命名空间
- 定向元素生成:使用
xsl:element显式指定元素的前缀和命名空间,替代xsl:copy,确保子元素始终以带前缀的形式输出 - 彻底移除foo命名空间:通过模板匹配直接跳过所有foo命名空间的节点和属性,避免冗余命名空间残留
- 保留原始格式:通用节点复制逻辑确保文本、注释等非命名空间内容与原始输出一致
效果验证
输入XML示例
<kookerella:root xmlns:kookerella="http://example.com/kookerella" xmlns:foo="http://example.com/foo"> <kookerella:wibble>Sample Content</kookerella:wibble> <foo:unwanted>Remove This</foo:unwanted> <text-node>Plain Text</text-node> </kookerella:root>
输出XML结果
<kookerella:root xmlns:kookerella="http://example.com/kookerella"> <kookerella:wibble>Sample Content</kookerella:wibble> <text-node>Plain Text</text-node> </kookerella:root>
内容的提问来源于stack exchange,提问作者MrD at KookerellaLtd
相关产品推荐
相关产品推荐

