如何使用xml.etree.ElementTree给XML新增节点添加命名空间?
如何给新增的XML节点添加指定命名空间前缀(使用xml.etree.ElementTree)
你当前使用xml.etree.ElementTree解析XML字符串并新增节点时,遇到了两个问题:直接新增的<category>节点不带ns0前缀;而直接在节点名前加ns0:会触发unbound prefix解析错误。以下是两种可行的解决方法:
问题回顾
原代码
import xml.etree.ElementTree as ET source_str = """<?xml version="1.0" encoding="UTF-8"?> <ns0:testcase xmlns:ns0="http://jazz.net/xmlns/alm/qm/v0.1/"> <ns0:category term="Platform Version" value="Linux_5.4"/> </ns0:testcase> """ xml_root = ET.fromstring(source_str) new_str = '<category term="Platform Version" value="Linux_6.6"/>' new_node = ET.fromstring(new_str) xml_root.append(new_node) final_str = ET.tostring(xml_root, encoding='utf-8').decode('utf-8') print(final_str)
执行结果
<ns0:testcase xmlns:ns0="http://jazz.net/xmlns/alm/qm/v0.1/"> <ns0:category term="Platform Version" value="Linux_5.4" /> <category term="Platform Version" value="Linux_6.6" /></ns0:testcase>
错误尝试及报错
若直接修改new_str为带ns0:的字符串:
new_str = '<ns0:category term="Platform Version" value="Linux_6.6"/>' new_node = ET.fromstring(new_str)
会触发解析错误:
Traceback (most recent call last): File "/home/nxa13855/test_xml.py", line 11, in <module> new_node = ET.fromstring(new_str) File "/usr/lib/python3.9/xml/etree/ElementTree.py", line 1347, in XML parser.feed(text) xml.etree.ElementTree.ParseError: unbound prefix: line 1, column 0
解决方法
方法一:直接创建带命名空间的节点(推荐)
利用ET.Element创建节点时,通过{命名空间URI}节点名的格式指定节点的命名空间,同时注册前缀与URI的映射,确保输出时使用ns0前缀:
import xml.etree.ElementTree as ET source_str = """<?xml version="1.0" encoding="UTF-8"?> <ns0:testcase xmlns:ns0="http://jazz.net/xmlns/alm/qm/v0.1/"> <ns0:category term="Platform Version" value="Linux_5.4"/> </ns0:testcase> """ # 注册命名空间前缀与URI的映射,避免输出时生成默认前缀(如ns1) ET.register_namespace('ns0', 'http://jazz.net/xmlns/alm/qm/v0.1/') xml_root = ET.fromstring(source_str) # 创建带命名空间的category节点,标签格式为{URI}节点名 new_node = ET.Element( '{http://jazz.net/xmlns/alm/qm/v0.1/}category', term="Platform Version", value="Linux_6.6" ) xml_root.append(new_node) final_str = ET.tostring(xml_root, encoding='utf-8').decode('utf-8') print(final_str)
方法二:在解析字符串时声明命名空间
如果必须通过XML字符串解析生成节点,需要在字符串中显式声明ns0对应的命名空间,让解析器识别前缀:
import xml.etree.ElementTree as ET source_str = """<?xml version="1.0" encoding="UTF-8"?> <ns0:testcase xmlns:ns0="http://jazz.net/xmlns/alm/qm/v0.1/"> <ns0:category term="Platform Version" value="Linux_5.4"/> </ns0:testcase> """ ET.register_namespace('ns0', 'http://jazz.net/xmlns/alm/qm/v0.1/') xml_root = ET.fromstring(source_str) # 在新节点的XML字符串中添加命名空间声明 new_str = '<ns0:category xmlns:ns0="http://jazz.net/xmlns/alm/qm/v0.1/" term="Platform Version" value="Linux_6.6"/>' new_node = ET.fromstring(new_str) xml_root.append(new_node) final_str = ET.tostring(xml_root, encoding='utf-8').decode('utf-8') print(final_str)
执行效果
两种方法均会输出符合预期的XML:
<ns0:testcase xmlns:ns0="http://jazz.net/xmlns/alm/qm/v0.1/"> <ns0:category term="Platform Version" value="Linux_5.4" /> <ns0:category term="Platform Version" value="Linux_6.6" /></ns0:testcase>
内容的提问来源于stack exchange,提问作者atline
相关产品推荐
相关产品推荐

