基本上,我想生成一个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结婚以获得解决方案,但我宁愿不必创建架构。提前感谢任何建议/解决方案!
答案 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')
<?xml version='1.0' encoding='utf-8'?>
<AllItems><Item><some_tag>Hello World ☺</some_tag></Item></AllItems>