Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Синтаксический разбор нецелых XML




XML спецификация предписывает, что все XML синтаксические анализаторы должны выполнять «драконову (строгую) обработку ошибок». То есть, при обнаружении в XML документе формальной ошибки или не «правильнопостроенности» (wellformedness) анализаторы должны сразу же прервать анализ и «вспыхнуть». Ошибки правильнопостроенности включают несогласованность открывающих и закрывающих тэгов, неопределённые элементы, неправильные символы Юникод и другие эзотерические ситуации. Такая обработка ошибок сильно контрастирует на фоне других известных форматов, например, HTML — браузер не останавливается отрисовывать web-страницу если в странице забыт закрывающий HTML тэг или значение атрибута тэга содержит неэкранированный амперсанд. (Существует распространённое заблуждение, что в формате HTML не оговорена обработка ошибок. На самом деле, обработка HTML ошибок отлично документирована, но она гораздо сложнее чем просто «остановиться и загореться на первой ошибке».)

Некоторые считают (и я в том числе), что это было ошибкой со стороны разработчиков формата XML заставлять так строго обрабатывать ошибки. Не поймите меня неправильно, я конечно же за упрощение правил обработки ошибок. Однако, на практике понятие «правильнопостроенности» оказывается коварнее чем кажется, особенно для XML документов которые публикуются в интернете и передаются по протоколу HTTP (например, фиды Atom). Несмотря на зрелость XML, который стандартизовал драконову обработку ошибок в 1997, исследования постоянно показывают, что значительная часть фидов Atom в интернете содержат ошибки правильнопостроенности.

Итак, у меня есть и теоретические и практические причины обрабатывать XML документы «любой ценой», то есть не останавливаться и взрываться при первой ошибке. Если Вы окажетесь в похожей ситуации, то lxml может помочь.

Ниже приведён фрагмент «битого» XML документа.

<?xml version='1.0' encoding='utf-8'?><feed xmlns='http://www.w3.org/2005/Atom' xml:lang='en'> <title>dive into &hellip;</title>...</feed>

В фиде ошибка, так как последовательность &hellip; не определена в формате XML (она определена в HTML). Если попробовать разобрать битый фид с настройками по умолчанию, то lxml споткнётся на неопределённом вхождении hellip.

>>> import lxml.etree>>> tree = lxml.etree.parse('examples/feed-broken.xml')Traceback (most recent call last): File "<stdin>", line 1, in <module> File "lxml.etree.pyx", line 2693, in lxml.etree.parse (src/lxml/lxml.etree.c:52591) File "parser.pxi", line 1478, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:75665) File "parser.pxi", line 1507, in lxml.etree._parseDocumentFromURL (src/lxml/lxml.etree.c:75993) File "parser.pxi", line 1407, in lxml.etree._parseDocFromFile (src/lxml/lxml.etree.c:75002) File "parser.pxi", line 965, in lxml.etree._BaseParser._parseDocFromFile (src/lxml/lxml.etree.c:72023) File "parser.pxi", line 539, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:67830) File "parser.pxi", line 625, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:68877) File "parser.pxi", line 565, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:68125)lxml.etree.XMLSyntaxError: Entity 'hellip' not defined, line 3, column 28

Для того чтобы обрабатывать XML документ с ошибками, необходимо создать новый синтаксический анализатор XML.

>> parser = lxml.etree.XMLParser(recover=True) ①>>> tree = lxml.etree.parse('examples/feed-broken.xml', parser) ②>>> parser.error_log ③examples/feed-broken.xml:3:28:FATAL:PARSER:ERR_UNDECLARED_ENTITY: Entity 'hellip' not defined>>> tree.findall('{http://www.w3.org/2005/Atom}title')[<Element {http://www.w3.org/2005/Atom}title at ead510>]>>> title = tree.findall('{http://www.w3.org/2005/Atom}title')[0]>>> title.text ④'dive into '>>> print(lxml.etree.tounicode(tree.getroot())) ⑤<feed xmlns='http://www.w3.org/2005/Atom' xml:lang='en'> <title>dive into </title>.. [остальной вывод сериализации пропущен для краткости].

① Для того чтобы создать новый анализатор мы создаём новый класс lxml.etree.XMLParser. Хотя он может принимать много разных параметров, для нас представляет интерес только один — аргумент восстановления recover. При присвоении аргументу значения True lxml будет из кожи вон лезть чтобы восстановить ошибки правильнопостроенности.

② Для того чтобы разобрать XML документ новым анализатором мы передаём объект parser в качестве второго аргумента в функцию parse(). На этот раз lxml не выбрасывает исключительную ситуацию при неопределённой последовательности &hellip;.

③ Анализатор содержит сообщения обо всех найденных ошибках. (На самом деле эти сообщения сохраняются независимо от параметра recover.)

④ Так как анализатор не знает что делать с неопределённым &hellip;, то он просто выбрасывает слово. Текстовое содержание элемента title превращается в 'dive into '.

⑤ И ещё раз: после сериализации последовательность &hellip; исчезла, lxml её выбросил.

Важно отметить, что нет никакой гарантии переносимости восстановления ошибок у XML анализаторов. Другой анализатор может быть умнее и распознать что &hellip; является валидной последовательностью HTML и восстановить её как амперсанд. «Лучше» ли это? Возможно. Является ли это «более правильным»? Нет, так как оба решения с точки зрения формата XML неверны. Правильное поведение (согласно XML спецификации) прекратить обработку и загореться. Если же необходимо не следовать спецификации, то Вы делаете это на свой страх и риск.





Поделиться с друзьями:


Дата добавления: 2016-11-18; Мы поможем в написании ваших работ!; просмотров: 338 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

В моем словаре нет слова «невозможно». © Наполеон Бонапарт
==> читать все изречения...

2174 - | 2121 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.006 с.