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

如何将XML中所有命名空间声明迁移至根节点?

可行,以下是实现方案

完全可以实现将所有命名空间声明移至根节点的需求,同时保留你现有XSLT模板的功能。核心思路是先收集文档中所有的命名空间,再在根节点统一输出这些命名空间,处理子元素时忽略它们自带的命名空间声明。

源XML示例

<top>
  <middle xmlns:first="http://test.com">
    <inner xmlns:second="http://somthing.com">
      Hello
    </inner>
  </middle>
</top>

期望输出XML

<top xmlns:first="http://test.com" xmlns:second="http://somthing.com">
  <middle>
    <inner>
      Hello
    </inner>
  </middle>
</top>

实现的XSLT代码(可与现有模板整合)

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 收集所有命名空间,存入变量(排除XSLT自身命名空间) -->
  <xsl:variable name="all-namespaces" as="element()*">
    <xsl:for-each select="//namespace::*[not(. = 'http://www.w3.org/1999/XSL/Transform') and not(local-name()='')]">
      <xsl:namespace name="{local-name()}"><xsl:value-of select="."/></xsl:namespace>
    </xsl:for-each>
  </xsl:variable>

  <!-- 根节点模板:输出根元素+所有收集到的命名空间 -->
  <xsl:template match="/">
    <xsl:element name="{name(/*)}">
      <xsl:copy-of select="$all-namespaces"/>
      <xsl:apply-templates select="/*/*"/>
    </xsl:element>
  </xsl:template>

  <!-- 通用元素模板:复制元素结构,但不复制命名空间属性 -->
  <xsl:template match="*">
    <xsl:element name="{name()}">
      <!-- 复制除命名空间声明外的其他属性 -->
      <xsl:copy-of select="@*[not(namespace-uri()='http://www.w3.org/2000/xmlns/')]"/>
      <!-- 处理子节点,自动调用现有自定义模板 -->
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

  <!-- 在这里添加你的其他自定义模板 -->
  <!-- 示例:修改inner元素文本的模板 -->
  <!--
  <xsl:template match="inner">
    <inner>
      <xsl:text>Modified Hello</xsl:text>
    </inner>
  </xsl:template>
  -->
</xsl:stylesheet>

整合现有模板的注意事项

  • 自定义模板的匹配模式要比通用元素模板更具体,或者通过priority属性设置更高优先级,确保原有逻辑正常执行
  • 如果使用XSLT 1.0,需要用exsl:node-set扩展函数处理节点集变量,XSLT 2.0及以上版本可直接使用上述代码
  • 通用模板会自动过滤所有命名空间属性,避免子元素重复输出命名空间声明

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:27:34