2010-06-14 2 views
5

я написал небольшую функцию, которая использует ElementTree и XPath для извлечения текстового содержимого определенных элементов в файле XML:Python + Expat: Ошибка на � лиц

#!/usr/bin/env python2.5 

import doctest 
from xml.etree import ElementTree 
from StringIO import StringIO 

def parse_xml_etree(sin, xpath): 
    """ 
Takes as input a stream containing XML and an XPath expression. 
Applies the XPath expression to the XML and returns a generator 
yielding the text contents of each element returned. 

>>> parse_xml_etree(
... StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'), 
... '//elem1').next() 
'one' 
>>> parse_xml_etree(
... StringIO('<test><elem1>one</elem1><elem2>two</elem2></test>'), 
... '//elem2').next() 
'two' 
>>> parse_xml_etree(
... StringIO('<test><null>&#0;</null><elem3>three</elem3></test>'), 
... '//elem2').next() 
'three' 
""" 

    tree = ElementTree.parse(sin) 
    for element in tree.findall(xpath): 
    yield element.text 

if __name__ == '__main__': 
    doctest.testmod(verbose=True) 

Третье испытание терпит неудачу со следующим исключение:

ExpatError: ссылка на недействительный номер символа: строка 1, столбец 13

ли &#0; организации незаконной XML? Независимо от того, является это или нет, файлы, которые я хочу проанализировать, содержат его, и мне нужно каким-то образом их проанализировать. Любые предложения для другого парсера, чем Expat, или настройки для Expat, которые позволили бы мне это сделать?


Обновление: Я обнаружил BeautifulSoup только сейчас, а тег суп анализатор, как указано ниже в ответ комментарии, и для удовольствия я вернулся к этой проблеме и попытался использовать его в качестве XML-уборщика перед ElementTree , но он покорно преобразовал &#0; в байт с нулевым недопустимым значением. :-)

cleaned_s = StringIO(
    BeautifulStoneSoup('<test><null>&#0;</null><elem3>three</elem3></test>', 
        convertEntities=BeautifulStoneSoup.XML_ENTITIES 
).renderContents() 
) 
tree = ElementTree.parse(cleaned_s) 

... дает

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 12 

В моем конкретном случае, хотя я на самом деле не нужен XPath синтаксический как таковой, я мог бы с самого BeautifulSoup и его довольно просто узловой адресный стиль parsed_tree.test.elem1.contents[0].

ответ

6

&#0; не находится в legal character range, определенном спецификацией XML. Увы, мои навыки Python довольно рудиментарны, так что я не очень им помог.

+0

Хм, да, спецификация делает это совершенно ясным. Спасибо за точную ссылку. – clacke

+0

Я понимаю, что это старый поток, но спецификация говорит, что * буквальные * символы могут появляться только в XML. Последовательность байтов � не * буквально * нулевой символ, а 4-символьная последовательность, которая * представляет * нулевой байт. Учитывая это различие, является � legal? Я не могу найти ничего в спецификации, которая говорит *, что * является незаконным. –

+1

Действительный вопрос. Но ответ здесь: http://www.w3.org/TR/REC-xml/#sec-references говорит: «Символы, ссылающиеся на использование ссылок на символы, должны соответствовать произведению для Char». – clacke

4

&#0; не является действительным символом XML. В идеале вы сможете заставить создателя файла изменить свой процесс, чтобы файл был недействителен, как этот.

Если вы хотите принять эти файлы, вы можете предварительно обработать их, чтобы превратить &#0 во что-то другое. Например, выберите @ в качестве escape-символа, превратите «@» в «@@» и «&#0;» в «@ 0».

Затем, когда вы получаете текстовые данные из анализатора, вы можете отменить отображение. Это просто пример, вы можете придумать любой синтаксис escaping, который вам нравится.

+0

В моем конкретном случае я мог просто удалить их. Они находятся в неуместном элементе XML. Нехорошо использовать текстовую обработку для обработки XML, но, поскольку он не является корректным, я предполагаю, что у меня нет выбора ... Использование какого-то анализатора супов для супов кажется излишним. – clacke

+0

Вы уверены, что алгоритм ускорения надежный? Разве вам не нужно учитывать приоритет функций в грамматике XML? –

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

  • Нет связанных вопросов^_^