XSLT根节点添加命名空间时子节点出现空xmlns属性的原因问询
问题根因
这个现象是XSLT遵循XML命名空间规范的标准处理逻辑,不是程序错误,核心触发逻辑如下:
- 你在生成根元素的
xsl:element标签上通过xmlns="http://www.element-examples.org"局部声明了默认命名空间,这个声明的作用域仅覆盖当前这一个手动创建的元素(即输出结果中的<projectgegevens>节点),不会自动继承到后续模板生成的所有子节点上。 - 你通过
<xsl:apply-templates select="@*|node()"/>处理子节点时,源XML里的这些子节点本身属于空命名空间(无命名空间),生成子元素时也没有手动指定归属到http://www.element-examples.org命名空间。 - XML的命名空间是默认继承的:如果父元素声明了默认命名空间,所有没前缀的子元素默认都会归属到这个命名空间下。为了保证子元素的空命名空间语义不被父元素的默认命名空间覆盖,XSLT序列化输出时会自动给这些子元素加上
xmlns="",用来重置默认命名空间,避免子元素被错误划分到父元素的命名空间下。
对应修复方案
根据你的实际需求选对应方案即可:
- 如果你需要所有输出元素都归属到
http://www.element-examples.org命名空间:不要只在单个xsl:element上局部声明默认命名空间,要给所有元素生成逻辑统一指定命名空间,最稳妥的方式是给xsl:element显式添加namespace属性,保证所有层级的元素生成时都绑定到目标命名空间,示例代码如下:
<xsl:element name="{local-name()}" namespace="http://www.element-examples.org"> <xsl:apply-templates select="@*|node()"/> </xsl:element>
注意要保证所有匹配元素的模板都用这段逻辑生成节点,不要只给根节点配置。
- 如果你本身就只要求根元素属于
http://www.element-examples.org命名空间,子元素需要保留空命名空间:那输出里的xmlns=""是完全符合XML规范的正确结果,不需要修改,这个属性只是序列化时自动添加的命名空间重置标记,不会影响XML的正常解析和数据读取。
内容的提问来源于stack exchange,提问作者Barney
相关产品推荐
相关产品推荐

