使用Python / Elementtree

时间:2018-03-13 15:28:40

标签: python xml elementtree

我正在从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)

但它没有帮助。

2 个答案:

答案 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)