使用xml.etree在Python中编写包含欧元符号(€)的xml文件

时间:2012-09-29 19:36:49

标签: python euro xml.etree

我正在尝试使用xml.etree来读取和写入包含€符号的xml文件。

我的简化代码如下所示:

optionsdirectory = os.getcwd()
optionsfile = os.path.join(optionsdirectory, "conf")
optionstree = ET.parse(optionsfile)
options = optionstree.getroot()
for option in options:
    if option.tag == "currency":
        option.text = "€"
optionstree.write(optionsfile, encoding="UTF-8")

运行时出现以下错误:

File "C:\curr.py", line 8
    optionstree.write(optionsfile, encoding="UTF-8")
File "C:\Python27\lib\xml\etree\ElementTree.py", line 815, in write
    serialize(write, self._root, encoding, qnames, namespaces)
File "C:\Python27\lib\xml\etree\ElementTree.py", line 934, in _serialize_xml
    _serialize_xml(write, e, encoding, qnames, None)
File "C:\Python27\lib\xml\etree\ElementTree.py", line 932, in _serialize_xml
    write(_escape_cdata(text, encoding))
File "C:\Python27\lib\xml\etree\ElementTree.py", line 1068, in _escape_cdata
    return text.encode(encoding, "xmlcharrefreplace")
UnicodeDecodeError: 'ascii' codec can't decode byte 0x80 in position 2114: ordinal not in range(128)

有没有办法使用xml.etree?

将€符号写入xml文件

3 个答案:

答案 0 :(得分:6)

您需要使用unicode文字。使用unicode转义符而不是字符会更容易:

option.text = u"\u20AC"  # Euro sign

当您不使用unicode文字而是使用字节(字符串)文字时会发生什么,是Python尝试使用默认编码(即ASCII)将值解码为unicode文字。这会导致您看到的UnicodeDecodeError。

如果你真的想要使用非转义字符,请确保在顶部指定源文件的编码:

# -*- coding: utf-8 -*-

并确保您的编辑器使用UTF-8保存文件。你仍然需要使用unicode文字:

option.text = u"€"

答案 1 :(得分:0)

以下是如何使用非ASCII字符创建XML文件。请注意,您需要将源文件保存在通过# coding:声明的编码中,并使用Unicode文字(u'string')。在下面的示例中,我将文件写为UTF-8和ASCII,以证明ElementTree将在任何一种情况下正确读取文件:

# coding: utf8
from xml.etree import ElementTree as et

# Create the root element.
root = et.Element('test')
root.text = u'123€456'

# Wrap the root in an ElementTree and write files.
tree = et.ElementTree(root)
tree.write('utf8.xml',encoding='UTF-8')
tree.write('ascii.xml',encoding='ascii')

# Verify that each file can be read correctly.
tree = et.parse('utf8.xml')
print tree.getroot().text
tree = et.parse('ascii.xml')
print tree.getroot().text

# display the raw contents of the files
with open('utf8.xml','rb') as f:
    print repr(f.read())
with open('ascii.xml','rb') as f:
    print repr(f.read())

注意输出。 0xE2 0x82 0xAC是欧元字符的UTF-8十六进制序列。 €是字符引用。

123€456
123€456
"<?xml version='1.0' encoding='UTF-8'?>\n<test>123\xe2\x82\xac456</test>"
"<?xml version='1.0' encoding='ascii'?>\n<test>123&#8364;456</test>"

答案 2 :(得分:0)

我认为我对网页很好,但对于我的生活,我无法弄清楚如何像其他人一样“响应”这个网站上的帖子。所以我需要创建这个新的答案......

感谢Mark Tolonen的回复。您的回复和Martijn Pieters的回复都涉及使用Unicode文字。然而,这对我不起作用。我正在使用的XML文件将通过写出包含€符号的文件名来创建。我通过以下代码获取文件名:

for file in os.listdir(r'C:\test'):
    filenamelist = filenamelist + " " + file

其中一些文件名将在文件名中包含€符号。然后,我想将这些文件名写为XML属性,如下所示:

optionsdirectory = os.getcwd()
optionsfile = os.path.join(optionsdirectory, "conf.xml")
optionstree = ET.parse(optionsfile)
options = optionstree.getroot()
for option in options:
    if option.tag == "filenames":
        option.text = filenamelist
optionstree.write(optionsfile, encoding="UTF-8")

最初我将有一个xml文件'conf.xml',它将包含一个空的'filenames'属性。我知道它很蹩脚,但它适用于我的目的。

因此,€符号不能来自Unicode文字。当我运行上面的代码时,我得到了我在原始帖子中发布的错误,这基本上说当它遇到'filenamelist'中的€符号时它会抛出它的手。