2015-12-05 2 views
1

В проекте python 3.5 мне нужно прочитать в некоторых xml-файлах, и я решил использовать библиотеку lxml. Поскольку я читаю файлы, наиболее эффективным способом сделать это в соответствии с документацией является чтение с использованием функции lxml.etree.parse (...).Пользовательский парсер Python lxml не работает с функцией lxml.etree.parse (...)

Проблема, с которой я сталкиваюсь, заключается в том, что эта функция всегда использует парсер по умолчанию, даже если я передаю пользовательский. Функция lxml.etree.fromstring (...) работает правильно.

Этот код показывает проблему, которую я имею. parse() дает тот же результат, если я даю ему путь к файлу.

from io import StringIO 
from lxml import etree 

class honk(etree.ElementBase): 
    pass 

parser_lookup = etree.ElementDefaultClassLookup(element=honk) 
parser = etree.XMLParser() 
parser.set_element_class_lookup(parser_lookup) 

elem1 = etree.parse(StringIO("<test/>"), parser) 
elem2 = etree.fromstring("<test/>", parser) 

print(isinstance(elem1, honk), type(elem1)) 
print(isinstance(elem2, honk), type(elem2)) 

Выход

False <class 'lxml.etree._ElementTree'> 
True <class '__main__.honk'> 

Я понятия не имею, что вызывает его или как ее решить. Я могу обойти это, но такая ошибка в библиотеке кажется странной.

ответ

4

Это потому, что parse() и fromstring() возвращает разные типы. Цитируется The lxml.etree Tutorial > The parse() function:

«Обратите внимание, что parse() возвращает ElementTree объекта, а не Element объекта как функция строки анализатора»

Чтобы получить эквивалентный тип, вам нужно позвонить getroot():

..... 
tree = etree.parse(StringIO("<test/>"), parser) 
elem1 = tree.getroot() 
elem2 = etree.fromstring("<test/>", parser) 

print(isinstance(elem1, honk), type(elem1)) 
print(isinstance(elem2, honk), type(elem2)) 

мощность:

True <class '__main__.honk'> 
True <class '__main__.honk'> 
Смежные вопросы