我正在从python字典中读取数据并尝试在下面的树中添加更多书元素。下面只是一个示例,我需要复制一个元素与它的孩子,但替换内容,在这种情况下,我需要复制书元素,但替换标题和作者。
<store>
<bookstore>
<book>
<title lang="en">IT book</title>
<author>Some IT Guy</author>
</book>
</bookstore>
</store>
我使用此代码:
root = et.parse('Template.xml').getroot()
bookstore = root.find('bookstore')
book = root.find('bookstore').find('book')
然后我通过字典运行循环并尝试在书店下添加新书元素:
for bk in bks:
book.find('title').text = bk
bookstore.append(book)
结果是书籍元素被添加到书店,但是它们都包含来自循环的最后一次迭代的标题。我知道我在这里做错了什么,但我无法理解。我试过了:
book[0].append(book) and book[-1].append(book)
但它没有帮助。
答案 0 :(得分:3)
您更改同一个对象。
您需要使用copy.deepcopy
实际复制对象示例:
import xml.etree.ElementTree as et
import copy
root = et.parse('Template.xml').getroot()
bookstore = root.find('bookstore')
book = root.find('bookstore').find('book')
bks = ["book_title_1", "book_title_2", "book_title_3"]
for bk in bks:
new_book = copy.deepcopy(book)
new_book.find('title').text = bk
bookstore.append(new_book)
print et.tostring(root)
答案 1 :(得分:2)
我猜不是books.append(book)
你的意思是bookstore.append(book)
。
基本上你有一个结构:
- store
- bookstore
- book
- book infos
book = root.find('bookstore').find('book')
你实际上得到了你已经拥有的(仅)的引用,并且在循环中你不断更新它的标题并将其重新附加到商店(所以基本上你只是覆盖了标题)。您必须做的是每次创建新Element
(或将其克隆为Chertkov Pavel建议时创建,但您必须记住覆盖所有字段,否则您最终可能会继承错误的作者)并将其附加到书店:
for bk in bks:
new_book = et.Element('book')
# create and append title
new_title = et.Element('title', attib={'lang':'eng'})
new_title.text = bk
new_book.append(new_title)
# add also author and any other info
# ...
# append to the bookstore
bookstore.append(new_book)
print et.tostring(root)