使用ElementTree.tostring的default_namespace参数报错,如何保留原XML命名空间?
解决ElementTree保留XML默认命名空间格式的问题
问题背景
需要用ElementTree修改XML文档,要求新文件保留原文件的默认命名空间格式(即不带前缀的xmlns="http://www.example.com/blabla/"),但使用ET.tostring或ET.write的default_namespace参数时会抛出ValueError: cannot use non-qualified names with default_namespace option错误。
原示例XML文件
<?xml version="1.0"?> <test xmlns="http://www.example.com/blabla/"> <item name="first" /> </test>
报错测试过程
Python 3.11.5 (tags/v3.11.5:cce6ba9, Aug 24 2023, 14:38:34) [MSC v.1936 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import xml.etree.ElementTree as ET >>> xml = ET.parse("test.xml") >>> ET.tostring(xml, default_namespace="http://www.example.com/blabla/") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "C:\Python311\Lib\xml\etree\ElementTree.py", line 1098, in tostring ElementTree(element).write(stream, encoding, File "C:\Python311\Lib\xml\etree\ElementTree.py", line 741, in write qnames, namespaces = _namespaces(self._root, default_namespace) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Python311\Lib\xml\etree\ElementTree.py", line 856, in _namespaces add_qname(key) File "C:\Python311\Lib\xml\etree\ElementTree.py", line 833, in add_qname raise ValueError( ValueError: cannot use non-qualified names with default_namespace option
解决方法:注册默认命名空间
ElementTree解析XML时,会将默认命名空间下的元素标签转换为{命名空间URI}本地名称的格式。要输出原格式的默认命名空间,只需注册空前缀到目标命名空间URI,无需使用default_namespace参数。
示例代码
import xml.etree.ElementTree as ET # 解析XML文件 tree = ET.parse("test.xml") root = tree.getroot() # 注册空前缀(即默认命名空间)到原URI ET.register_namespace('', 'http://www.example.com/blabla/') # 示例:修改XML内容,添加新元素 new_item = ET.Element('{http://www.example.com/blabla/}item') new_item.set('name', 'second') root.append(new_item) # 输出XML字符串 xml_str = ET.tostring(root, encoding='utf-8', xml_declaration=True) print(xml_str.decode('utf-8')) # 写入新文件 tree.write("modified_test.xml", encoding='utf-8', xml_declaration=True)
输出结果
生成的XML将与原文件格式一致:
<?xml version='1.0' encoding='utf-8'?> <test xmlns="http://www.example.com/blabla/"> <item name="first" /> <item name="second" /> </test>
错误原因说明
default_namespace参数用于将无命名空间的元素映射到指定默认命名空间,但解析后的元素标签已带有原命名空间URI(如{http://www.example.com/blabla/}test),此时使用该参数会引发命名空间冲突,触发报错。注册空命名空间后,ElementTree会自动将带该URI的元素输出为默认命名空间格式,无需额外指定default_namespace。
内容的提问来源于stack exchange,提问作者treuss
相关产品推荐
相关产品推荐

