2014-02-11 4 views
10

Мне нужна помощь, чтобы понять, почему синтаксический анализ моего xml-файла * с помощью xml.etree.ElementTree вызывает следующие ошибки.Как правильно разобрать utf-8 xml с 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' 

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

ответ

7

Оставить декодирование байтов в парсер; сделать не расшифровывает первое:

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.

+0

Отлично, казалось, было легче, чем я думал. Даже файлы «utf-8 без спецификации» корректно анализируются. – minerals

+0

UTF-8 без спецификации - стандарт; * with * BOM - это в основном Microsoft, которая хочет упростить автоопределение 8-битных кодировок, отличных от UTF-8. –

+1

'etree.parse (a_file)' обрабатывает Unicode по умолчанию. Однако 'etree.fromstring (a_string)' не работает до Python 3.x (см. Http://bugs.python.org/issue11033), поэтому для синтаксического анализа строки вам необходимо закодировать ее вручную, например 'etree.fromstring (a_string.encode ('UTF-8')) '. –

Смежные вопросы