使用Python 3.2从头开始创建Unicode XML

时间:2012-12-13 01:45:34

标签: python xml unicode python-3.x xml.etree

基本上,我想生成一个XML,其中包含从python词典中的数据生成的元素,其中将成为标记的是字典的键,而文本是字典的值。我没有必要为这些项提供属性,我想要的输出看起来像这样:

<AllItems>

  <Item>
    <some_tag> Hello World </some_tag>
    ...
    <another_tag />
  </Item>

  <Item> ... </Item>
  ...

</AllItems>

我尝试使用xml.etree.ElementTree包,通过创建树,将Element“AllItems”设置为根,如下所示:

from xml.etree import ElementTree as et

def dict_to_elem(dictionary):
    item = et.Element('Item')
    for key in dictionary:
        field = et.Element(key.replace(' ',''))
        field.text = dictionary[key]
        item.append(field)
    return item

newtree = et.ElementTree()
root = et.Element('AllItems')
newtree._setroot(root)

root.append(dict_to_elem(  {'some_tag':'Hello World', ...}  )
# Lather, rinse, repeat this append step as needed

with open(  filename  , 'w', encoding='utf-8') as file:
    tree.write(file, encoding='unicode')

在最后两行中,我尝试在open()语句中省略编码,在write()方法中省略并更改为'UTF-8'编码,我得到一个错误“')是类型str不可序列化

所以我的问题 - 我想知道的是我应该如何使用上面的格式从头开始创建UTF-8 XML,并且使用另一个包有更强大的解决方案,这将适当地允许我处理UTF-8字符?我没有与ElementTree结婚以获得解决方案,但我宁愿不必创建架构。提前感谢任何建议/解决方案!

2 个答案:

答案 0 :(得分:6)

在我看来,ElementTree是一个不错的选择。如果将来需要更强大的软件包,可以切换到使用相同接口的第三方lxml模块。

您可以在文档http://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree.write

中找到问题的答案
  

输出是字符串(str)或二进制(字节)。这由encoding参数控制。如果编码是“unicode”,则输出是一个字符串;否则,它是二进制的。请注意,如果它是一个打开的文件对象,这可能与文件类型冲突;确保你不要尝试将字符串写入二进制流,反之亦然。

基本上,你正确地做到了。您以文本模式open()文件,这样文件接受字符串,您需要使用'unicode'的{​​{1}}参数。否则,您可以以二进制模式打开文件(tree.write()中没有编码参数)并使用open()中的'utf-8'

一个可以自行运行的清理代码:

tree.write()

这取决于目的。在这两者中,我个人更喜欢第一种解决方案。它清楚地说你写了一个文本文件(而XML是一个文本文件)。

但是,您不需要告诉编码的最简单的替代方法就是将文件名传递给#!python3 from xml.etree import ElementTree as et def dict_to_elem(dictionary): item = et.Element('Item') for key in dictionary: field = et.Element(key.replace(' ','')) field.text = dictionary[key] item.append(field) return item root = et.Element('AllItems') # create the element first... tree = et.ElementTree(root) # and pass it to the created tree root.append(dict_to_elem( {'some_tag':'Hello World', 'xxx': 'yyy'} )) # Lather, rinse, repeat this append step as needed filename = 'a.xml' with open(filename, 'w', encoding='utf-8') as file: tree.write(file, encoding='unicode') # The alternative is... fname = 'b.xml' with open(fname, 'wb') as f: tree.write(f, encoding='utf-8') ,如下所示:

tree.write

它打开文件,使用给定的编码写入内容(在下面的Sebastian评论后更新),然后关闭文件。你可以轻松阅读它,你可以在这里搞错。

答案 1 :(得分:5)

没有必要,但如果您的工具不理解生成的xml文件,则可以显式添加xml声明:

#!/usr/bin/env python3
from xml.etree import ElementTree as etree

your_dict = {'some_tag': 'Hello World ☺'}

def add_items(root, items):
    for name, text in items:
        elem = etree.SubElement(root, name)
        elem.text = text

root = etree.Element('AllItems')
add_items(etree.SubElement(root, 'Item'),
          ((key.replace(' ', ''), value) for key, value in your_dict.items()))
tree = etree.ElementTree(root)
tree.write('output.xml', xml_declaration=True, encoding='utf-8')

的Output.xml:

<?xml version='1.0' encoding='utf-8'?>
<AllItems><Item><some_tag>Hello World ☺</some_tag></Item></AllItems>