Skip to main content
 首页 » 编程设计

python之在 Python 中通过 ElementTree 解析 xml 时如何保留命名空间

2025年05月04日21Leo_wl

假设我有以下 XML,我想使用 Python 的 ElementTree 修改它:

<root xmlns:prefix="URI"> 
  <child company:name="***"/> 
  ... 
</root>  

我正在像这样对 XML 文件做一些修改:

import xml.etree.ElementTree as ET 
tree = ET.parse('filename.xml') 
# XML modification here 
# save the modifications 
tree.write('filename.xml') 

然后 XML 文件看起来像:

<root xmlns:ns0="URI"> 
  <child ns0:name="***"/> 
  ... 
</root> 

如您所见,命名空间 prefix 更改为 ns0。我知道使用 ET.register_namespace() 如前所述 here .

ET.register_namespace() 的问题在于:

  1. 您需要了解prefix 和URI
  2. 它不能与默认命名空间一起使用。

例如如果 xml 如下所示:

<root xmlns="http://uri"> 
    <child name="name"> 
    ... 
    </child> 
</root> 

它将被转换成类似这样的东西:

<ns0:root xmlns:ns0="http://uri"> 
    <ns0:child name="name"> 
    ... 
    </ns0:child> 
</ns0:root> 

如您所见,默认命名空间已更改为 ns0。

有什么方法可以用ElementTree解决这个问题吗?

请您参考如下方法:

ElementTree 将替换那些未在 ET.register_namespace 中注册的 namespace 前缀。要保留命名空间前缀,您需要先注册它,然后再将您的修改写入文件。以下方法完成工作并在全局注册所有命名空间,

def register_all_namespaces(filename): 
    namespaces = dict([node for _, node in ET.iterparse(filename, events=['start-ns'])]) 
    for ns in namespaces: 
        ET.register_namespace(ns, namespaces[ns]) 

此方法应在ET.parse 方法之前调用,这样命名空间将保持不变,

import xml.etree.ElementTree as ET 
register_all_namespaces('filename.xml') 
tree = ET.parse('filename.xml') 
# XML modification here 
# save the modifications 
tree.write('filename.xml')