13

次のように 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 文字は保持されません。何が起こっている?

4

1 に答える 1

29

codecs.openUnicode 文字列がファイル オブジェクトに書き込まれることを期待し、UTF-8 へのエンコードを処理します。ElementTreewriteは、ファイル オブジェクトに送信する前に、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()
于 2012-04-06T20:09:16.860 に答える