Как правильно разобрать utf-8 xml с ElementTree?

Мне нужна помощь, чтобы понять, почему синтаксический анализ моего xml файла * с помощью xml.etree.ElementTree вызывает следующие ошибки.

* Мой тестовый XML файл содержит арабские символы.

Задача: Откройте и проанализируйте 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)

Моя вторая попытка:

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'

Пожалуйста, объясните вышеописанные ошибки и прокомментируйте возможное решение.

Ответ 1

Оставить декодирование байтов в синтаксический анализатор; сначала не декодировать:

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 снова попытался закодировать значения Unicode, чтобы парсер мог обрабатывать строки байтов, как ожидалось. Вторая попытка потерпела неудачу, потому что etree.tostring() ожидает, что проанализированное дерево будет первым аргументом, а не строкой unicode.