Python ElementTree - 插入元素的副本

3 投票
3 回答
6390 浏览
提问于 2025-04-17 19:45

我有以下的xml代码:

<data factor="1" name="ini" value="342" />

我想复制相同的信息,但换个名字。也就是说,最后的输出应该是:

<data factor="1" name="ini" value="342" />
<data factor="1" name="raw_ini" value="342" />

我尝试做了以下操作:

model_tag = tree.findall(data_path) #I make sure that data_path is correct.
len_tags = len(model_tag)
i = 0
while i < len_tags: 
    tipo_tag = model_tag[i]
    if tipo_tag.attrib['name']=='ini':
        aux_tag = copy.deepcopy(tipo_tag) #I tried also with copy.copy(tipo_tag).
        aux_tag.attrib['name'] = 'raw_ini'
        model_tag.append(aux_tag)

tree.write(dir_output) 

如果我使用“copy.deepcopy”,我没有额外的元素。输出是:

<data factor="1" name="ini" value="342" />

如果我使用“copy.copy”,只是改变了元素的名字。输出是:

<data factor="1" name="raw_ini" value="342" />

你觉得我哪里做错了?

3 个回答

0

为了将来参考。

这里有一个最简单的方法,可以复制一个节点(或者树),同时保留它的子节点,而不需要为了这个目的再引入另一个库:

import xml.etree.ElementTree;

def copy_tree( tree_root ):
    return et.ElementTree( tree_root );

duplicated_node_tree = copy_tree ( node );    # type(duplicated_node_tree) is ElementTree
duplicated_tree_root_element = new_tree.getroot();  # type(duplicated_tree_root_element) is Element
1

在上面的例子中,“copy”和“dataElem”是从哪里来的呢?也就是说,copyElem = copy.deepcopy(dataElem) 这行代码中的 copy 和 dataElem 是什么?

1

你需要找到那些 data 元素的父级,然后使用 Element.insert(index, element) 方法来插入元素。

另外,你要用 deepcopy 而不是 copy。它们的区别在于,deepcopy 会创建一个新的对象,而使用 copy(它返回的是一个浅拷贝)时,你只是修改了第一个元素(就像你已经发现的那样)。

假设你有 dataParent 作为 data 元素的父级。

listData = dataParent.findall('data')
lenData = len(listData)
i = 0
while i < lenData:
    if listData[i].attrib['name'] == 'ini':
        copyElem = copy.deepcopy(dataElem)
        copyElem['name'] = 'raw_ini'
        dataParent.insert([index you wish], copyElem)
    i += 1

撰写回答