2010-10-23 32 views
24

Làm thế nào để sao chép các đối tượng Element trong Python xml.etree? Tôi đang cố gắng di chuyển và sao chép theo thủ tục (sau đó sửa đổi các thuộc tính của họ) các nút.etree Clone Node

Trả lời

30

Bạn chỉ có thể sử dụng copy.deepcopy() để tạo bản sao của phần tử. (điều này cũng sẽ làm việc với lxml bằng cách này).

+4

Điều đó tạo một bản sao, nhưng nó không được thêm vào cây. Bạn sẽ cần phải làm một 'append()' hoặc 'insert()' để làm điều đó. –

+0

điều này cũng làm việc với cElementTree bằng cách này ;-) – Thierry

0

Nếu bạn có một tay cầm ở Elementelem 's parent bạn có thể gọi

new_element = SubElement(parent, elem.tag, elem.attrib) 

Nếu không, bạn có thể muốn thử

new_element = makeelement(elem.tag, elem.attrib) 

nhưng điều này là không đúng đắn.

+2

Tôi nghĩ rằng họ không sao chép các nút con .. –

+0

@SHiNKiROU Bạn có thể so sánh 'id (old_element)' với 'id (new_element)' để xem nó có thực sự tạo một đối tượng khác trong bộ nhớ hay không. Không giúp đỡ à? –

+0

Như @ Ming-Tang đề cập, điều này ** không ** sao chép trẻ em. – halloleo

3

Một khác nhau, và có phần đáng lo ngại giải pháp:

new_element = lxml.etree.fromstring(lxml.etree.tostring(elem)) 
1

Ít nhất bằng Python 2.7 etree phần tử có một phương thức sao chép: http://hg.python.org/cpython/file/2.7/Lib/xml/etree/ElementTree.py#l233

Nó là một bản sao cạn, nhưng đó là một lợi thế trong một số trường hợp .

Trong trường hợp của tôi, tôi đang sao chép một số phần tử SVG và thêm biến đổi. Trẻ em sao chép sẽ không phục vụ bất kỳ mục đích nào kể từ khi có liên quan mà chúng đã thừa hưởng biến đổi của cha mẹ chúng.

+3

Đối với bất kỳ ai sử dụng điều này và nghĩ đến việc thay thế * xml.etree.ElementTree * bằng * lxml.etree * trong tương lai, lưu ý rằng 'Element.copy()' không tồn tại trong * lxml.etree *, và 'copy.copy()' cũng sao chép trẻ em, khi được áp dụng cho một 'lxml.etree.Element'. – meowsqueak

+0

Không hoạt động với cElementTree (Python 2.7). Vì vậy, thích copy.copy() (bản sao nông) hoặc copy.deepcopy() cho mã evolutivity. – Thierry

-1

Để tham khảo sau này.

đơn giản nhất cách để sao chép một nút (hoặc cây) và giữ nó là trẻ em, mà không cần phải nhập khẩu KHÁC thư viện CHỈ cho rằng:

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 
+0

Để rõ ràng, đây không phải là một bản sao sâu. (Có, bài viết nói "và giữ con cái của nó", nhưng tôi vẫn cảm thấy cần phải kiểm tra ý nghĩa của nó.) – harpo