使用lxml.etree复制XML元素时命名空间丢失问题求助
解决lxml.etree复制XML元素时命名空间前缀丢失问题
使用lxml.etree拼接XML文件时,复制后的<a:value>元素丢失了命名空间前缀,变成了<value>,需要保持与原元素一致的<a:value>格式。
输入文件 Input.xml
<?xml version="1.0" encoding="UTF-8"?> <haul> <uuid>abc</uuid> <port xmlns="hello" xmlns:a="hello"> <v> <a:value>0</a:value> <type>int</type> </v> </port> </haul>
测试代码 test.py
tree = load_tree_from_file('Input.xml') port = tree.find('{hello}port') v = port.find('{hello}v') v2=copy.deepcopy(v) port.append(v2) d = os.path.dirname(__file__) tree.write(os.path.join(d, 'Output.xml'))
当前输出 Output.xml
<haul> <uuid>abc</uuid> <port xmlns="hello" xmlns:a="hello"> <v> <a:value>0</a:value> <type>int</type> </v> <v> <value>0</value> <type>int</type> </v> </port> </haul>
解决方案
问题出在使用copy.deepcopy复制元素,它没有完整保留lxml内部的命名空间前缀绑定信息。改用lxml元素自带的copy()方法即可解决:
修改后的代码
import os from lxml import etree def load_tree_from_file(path): return etree.parse(path) tree = load_tree_from_file('Input.xml') port = tree.find('{hello}port') v = port.find('{hello}v') # 使用lxml Element自带的copy方法,保留命名空间上下文 v2 = v.copy() port.append(v2) d = os.path.dirname(__file__) # 写入时指定编码和XML声明,保持输入格式一致 tree.write(os.path.join(d, 'Output.xml'), encoding='UTF-8', xml_declaration=True)
说明
lxml的Element.copy()方法会完整复制元素的所有属性、子节点以及所在的命名空间环境(包括前缀与URI的绑定关系),而copy.deepcopy仅复制节点的基础结构,丢失了lxml特有的命名空间上下文,导致输出时无法正确映射前缀。
内容的提问来源于stack exchange,提问作者Cody Smith
相关产品推荐
相关产品推荐

