Я записал небольшую функцию, которая использует ElementTree и xpath для извлечения текстового содержания определенных элементов в XML-файле:
#!/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('one two '),
... '//elem1').next()
'one'
>>> parse_xml_etree(
... StringIO('one two '),
... '//elem2').next()
'two'
>>> parse_xml_etree(
... StringIO('three '),
... '//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
объект недопустимый XML? Независимо, ли это или нет, файлы, которые я хочу проанализировать, содержат его, и мне нужен некоторый способ проанализировать их. Какие-либо предложения для другого синтаксического анализатора, чем Эмигрант или настройки для Эмигранта, который позволил бы мне делать это?
Обновление: Я обнаружил BeautifulSoup сейчас, синтаксический анализатор супа тега, как отмечено ниже в комментарии ответа, и для забавы я вернулся к этой проблеме и попытался использовать ее в качестве XML-инструмента-для-очистки перед ElementTree, но это покорно преобразовало в just-as-invalid пустой байт.:-)
cleaned_s = StringIO(
BeautifulStoneSoup('three ',
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]
.
не входит в законный диапазон символов, определенный спецификацией XML. Увы, мои навыки работы с Python довольно примитивны, поэтому я не очень-то могу помочь.
& # 0;
не является допустимым символом XML. В идеале вы могли бы заставить создателя файла изменить свой процесс, чтобы файл не был недействительным.
Если вы должны принять эти файлы, вы можете предварительно обработать их, чтобы превратить & # 0
во что-то другое. Например, выберите @ в качестве escape-символа, превратите «@» в «@@», а « & # 0;
» в «@ 0».
Затем, когда вы получаете текстовые данные от анализатора, вы можете отменить отображение. Это всего лишь пример, вы можете придумать любой синтаксис экранирования, который вам нравится.