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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 13:33:27