6

所以基本上,我想用从python字典中的数据生成的元素生成一个XML,其中的标签是字典的键,文本是字典的值。我不需要为项目提供属性,我想要的输出看起来像这样:

<AllItems>

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

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

</AllItems>

我尝试使用 xml.etree.ElementTree 包,通过创建树,将元素“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 结婚以获得解决方案,但我宁愿不必创建模式。提前感谢您的任何建议/解决方案!

4

2 回答 2

7

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

您的问题的答案可以在文档http://docs.python.org/3/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree.write中找到

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

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

一些独立工作的清理代码:

#!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')

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

但是,您不需要告诉编码的最简单的替代方法是将文件名传递给tree.write这样的:

tree.write('c.xml', encoding='utf-8')

它打开文件,使用给定的编码写入内容(在下面塞巴斯蒂安的评论后更新),然后关闭文件。而且您可以轻松阅读它,并且在这里不会出错。

于 2012-12-13T08:45:12.427 回答
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:

<?xml version='1.0' encoding='utf-8'?>
<AllItems><Item><some_tag>Hello World ☺&lt;/some_tag></Item></AllItems>
于 2012-12-13T11:58:56.690 回答