web-dev-qa-db-ja.com

ElementTreeでutf-8 xmlを正しく解析する方法は?

xml.etree.ElementTreeでxmlファイル*を解析すると、次のエラーが発生する理由を理解するのに助けが必要です。

*テストxmlファイルにアラビア文字が含まれています。

Task:開いて解析utf8_file.xmlファイル。

私の最初の試み:

import xml.etree.ElementTree as etree
with codecs.open('utf8_file.xml', 'r', encoding='utf-8') as utf8_file:
    xml_tree = etree.parse(utf8_file)

結果1:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 236-238: ordinal not in range(128)

2回目の試行:

import xml.etree.ElementTree as etree
with codecs.open('utf8_file.xml', 'r', encoding='utf-8') as utf8_file:
    xml_string = etree.tostring(utf8_file, encoding='utf-8', method='xml')
    xml_tree  = etree.fromstring(xml_string)

結果2:

AttributeError: 'file' object has no attribute 'getiterator'

上記のエラーを説明し、可能な解決策についてコメントしてください。

15
minerals

バイトのデコードはパーサーに任せます。最初にデコードしない

_import xml.etree.ElementTree as etree
with open('utf8_file.xml', 'r') as xml_file:
    xml_tree = etree.parse(xml_file)
_

XMLファイルは、パーサーによるデコードを処理するのに十分な情報を最初の行に含む必要があります。ヘッダーがない場合、パーサーはUTF-8が使用されていると想定する必要があります。

この情報を保持するのはXMLヘッダーなので、すべてのデコードを行うのはパーサーの責任です。

Pythonがencode Unicode値を再試行して、パーサーが期待どおりにバイト文字列を処理できるようにしたため、最初の試行は失敗しました。2番目の試行はetree.tostring()は、Unicode文字列ではなく、解析されたツリーを最初の引数として期待します。

14
Martijn Pieters