Я работал над кодом, который анализирует внешние XML файлы. Некоторые из этих файлов огромны, до гигабайт данных. Излишне говорить, что эти файлы нужно анализировать как поток, потому что загрузка их в память слишком неэффективна и часто приводит к проблемам OutOfMemory.
Я использовал библиотеки miniDOM, ElementTree, cElementTree, и в настоящее время я использую lxml.
Сейчас у меня есть рабочий, довольно эффективный с точки зрения памяти script, используя lxml.etree.iterparse
. Проблема в том, что некоторые из файлов XML, которые мне нужны для синтаксического анализа, содержат ошибки кодирования (они рекламируют как UTF-8, но содержат символы, кодированные по-разному). При использовании lxml.etree.parse
это можно устранить, используя опцию recover=True
настраиваемого анализатора, но iterparse
не принимает пользовательский парсер. (см. также этот вопрос)
Мой текущий код выглядит следующим образом:
from lxml import etree
events = ("start", "end")
context = etree.iterparse(xmlfile, events=events)
event, root_element = context.next() # <items>
for action, element in context:
if action == 'end' and element.tag == 'item':
# <parse>
root_element.clear()
Ошибка, когда iterparse
встречает плохой символ (в этом случае это a ^Y
):
lxml.etree.XMLSyntaxError: Input is not proper UTF-8, indicate encoding !
Bytes: 0x19 0x73 0x20 0x65, line 949490, column 25
Я даже не хочу расшифровывать эти данные, я могу просто отказаться от него. Однако я не знаю, как пропустить элемент - я пробовал context.next
и continue
в операторах try/except.
Любая помощь будет оценена!
Обновление
Дополнительная информация: Это строка, в которой выполняется ошибка iterparse:
<description><![CDATA:[musea de la photographie fonds mercator. Met meer dan 80.000 foto^Ys en 3 miljoen negatieven is het Muse de la...]]></description>
В соответствии с etree ошибка возникает в байтах 0x19 0x73 0x20 0x65
.
Согласно hexedit, 19 73 20 65
переводится в ASCII .s e
.
в этом месте должен быть апострофом (foto's).
Я также нашел этот вопрос, который не дает решения.