【问题标题】:Write xml utf-8 file with utf-8 data with ElementTree使用 ElementTree 编写带有 utf-8 数据的 xml utf-8 文件
【发布时间】:2012-04-20 06:20:58
【问题描述】:

我正在尝试使用 ElementTree 编写一个带有 utf-8 编码数据的 xml 文件,如下所示:

#!/usr/bin/python                                                                       
# -*- coding: utf-8 -*-                                                                   

import xml.etree.ElementTree as ET
import codecs

testtag = ET.Element('unicodetag')
testtag.text = u'Töreboda' #The o is really ö (o with two dots over). No idea why SO dont display this
expfile = codecs.open('testunicode.xml',"w","utf-8-sig")
ET.ElementTree(testtag).write(expfile,encoding="UTF-8",xml_declaration=True)
expfile.close()

这会因错误而崩溃

Traceback (most recent call last):
  File "unicodetest.py", line 10, in <module>
    ET.ElementTree(testtag).write(expfile,encoding="UTF-8",xml_declaration=True)
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 815, in write
    serialize(write, self._root, encoding, qnames, namespaces)    
  File "/usr/lib/python2.7/xml/etree/ElementTree.py", line 932, in _serialize_xml
    write(_escape_cdata(text, encoding))
  File "/usr/lib/python2.7/codecs.py", line 691, in write
    return self.writer.write(data)
  File "/usr/lib/python2.7/codecs.py", line 351, in write
    data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)

使用“us-ascii”编码可以正常工作,但不要保留数据中的 unicode 字符。发生了什么?

【问题讨论】:

    标签: python elementtree


    【解决方案1】:

    codecs.open 期望将 Unicode 字符串写入文件对象,并将处理编码为 UTF-8。 ElementTree 的write 将Unicode 字符串编码为UTF-8 字节字符串,然后再将它们发送到文件对象。由于文件对象需要 Unicode 字符串,它使用默认的 ascii 编解码器将字节字符串强制回 Unicode,并导致 UnicodeDecodeError

    这样做:

    #expfile = codecs.open('testunicode.xml',"w","utf-8-sig")
    ET.ElementTree(testtag).write('testunicode.xml',encoding="UTF-8",xml_declaration=True)
    #expfile.close()
    

    【讨论】:

    • +1。只是为了澄清这一点:问题是您尝试对 unicode->utf-8 进行两次编码:ElementTree 执行一次,然后启用编解码器的流尝试再次执行此操作。但是第二次传递变得混乱,因为它的输入已经编码(它需要一个 unicode 字符串,但得到一个 utf-8 编码的字节字符串)。
    • 在这里,我一直认为我正在通过提供 unicode 文件来提供帮助...我可以说我喜欢 stackoverflow 吗? 3小时内完美解答!标记的详细说明也解释了很多。
    • 我一直在处理 utf-8 数据,并在尝试写入 xml 文件时在 ElementTree._serialize_text() 或 _serialize_xml() 中收到了类似的错误。在将字符串添加到我的 ET.Element 对象之前,我能够通过使用 myString.decode('utf-8') 将字符串转换为 unicode 来解决它。似乎 ET.ElementTree.write() 对其他字符串编码不满意。
    猜你喜欢
    • 1970-01-01
    • 2015-01-27
    • 2017-01-16
    • 2011-03-16
    • 2023-03-24
    • 2012-11-07
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    相关资源
    最近更新 更多