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

使用cleanup_namespaces无法移除XML命名空间,如何解决?

问题描述

我有如下XML字符串:

<exta>
<signature>This </signature>
<begin_date>2019-07-12T09:41:48.187</begin_date>
<ver>4</ver>
<maiden_bc>1549</maiden_bc>
<exta_id>12345</exta_id>
<nps_max_price xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <exta_id>72723</exta_id>
    <extended_datetime>2018-11-20T11:01:29.040</extended_datetime>
    <event_ind>E</event_ind>
    <maiden>12345</maiden>
    <patient_id>123</patient_id>
    <boss_id>123LHF</boss_id>
    <template_name/>
    <end_date>2019-01-01T00:00:00</end_date>
    <UYI_AMN xsi:nil="true"/>
    <dedt_bef_ATS xsi:nil="true"/>
    <form>W</form>
</nps_max_price>
</exta>

尝试使用cleanup_namespaces移除XML中的命名空间,代码如下:

from lxml import etree
root = etree.fromstring(xml)
for elem in root.getiterator():
    elem.tag = etree.QName(elem).localname

etree.cleanup_namespaces(root)
print(etree.tostring(root).decode())

执行后输出仍保留xmlns:xsi和xsi:nil等命名空间相关内容,但期望移除所有命名空间相关内容,得到如下XML:

<exta>
<signature>This </signature>
<begin_date>2019-07-12T09:41:48.187</begin_date>
<ver>4</ver>
<maiden_bc>1549</maiden_bc>
<exta_id>12345</exta_id>
<nps_max_price>
    <exta_id>72723</exta_id>
    <extended_datetime>2018-11-20T11:01:29.040</extended_datetime>
    <event_ind>E</event_ind>
    <maiden>12345</maiden>
    <patient_id>123</patient_id>
    <boss_id>123LHF</boss_id>
    <template_name/>
    <end_date>2019-01-01T00:00:00</end_date>
    <UYI_AMN/>
    <dedt_bef_ATS/>
    <form>W</form>
</nps_max_price>
</exta>
解决方案

etree.cleanup_namespaces()只会清理未被使用的命名空间声明,但xsi:nil是正在被使用的属性,所以不会自动移除。要完全清除所有命名空间相关内容,需要手动处理:

  1. 遍历所有元素,移除带有命名空间的属性(如xsi:nil)
  2. 移除元素上的命名空间声明属性(如xmlns:xsi)
  3. 同时保留之前的标签本地名处理

修改后的代码如下:

from lxml import etree

xml = '''
<exta>
<signature>This </signature>
<begin_date>2019-07-12T09:41:48.187</begin_date>
<ver>4</ver>
<maiden_bc>1549</maiden_bc>
<exta_id>12345</exta_id>
<nps_max_price xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <exta_id>72723</exta_id>
    <extended_datetime>2018-11-20T11:01:29.040</extended_datetime>
    <event_ind>E</event_ind>
    <maiden>12345</maiden>
    <patient_id>123</patient_id>
    <boss_id>123LHF</boss_id>
    <template_name/>
    <end_date>2019-01-01T00:00:00</end_date>
    <UYI_AMN xsi:nil="true"/>
    <dedt_bef_ATS xsi:nil="true"/>
    <form>W</form>
</nps_max_price>
</exta>
'''

root = etree.fromstring(xml)

# 处理所有元素
for elem in root.iter():
    # 移除元素标签的命名空间,保留本地名
    elem.tag = etree.QName(elem).localname
    
    # 移除所有带命名空间的属性和命名空间声明属性
    to_remove = []
    for attr_name in elem.attrib:
        # 带命名空间的属性键会包含{},比如{http://...}nil
        if '{' in attr_name or attr_name.startswith('xmlns:'):
            to_remove.append(attr_name)
    for attr in to_remove:
        del elem.attrib[attr]

# 清理残留的空命名空间声明
etree.cleanup_namespaces(root)

print(etree.tostring(root, encoding='unicode', pretty_print=True))

代码说明

  • 使用root.iter()遍历所有层级的元素,确保不遗漏子元素
  • 替换元素标签为本地名,彻底去掉命名空间前缀
  • 筛选并移除两类属性:带命名空间的属性(键含{})和命名空间声明属性(以xmlns:开头)
  • 最后调用cleanup_namespaces确保没有残留的无效命名空间声明

执行这段代码后,就能得到完全移除所有命名空间相关内容的XML。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:57:42