Как вернуть данные из анализатора SAX Python?

Я пытаюсь разобрать огромные XML-файлы, которые LXML не будет проверять, поэтому я вынужден разобрать их с помощью xml.sax .

 class SpamExtractor(sax.ContentHandler): def startElement(self, name, attrs): if name == "spam": print("We found a spam!") # now what? 

Проблема в том, что я не понимаю, как реально return или, лучше, yield , то, что этот обработчик обнаруживает вызывающему, не дожидаясь анализа всего файла. До сих пор я возился с threading.Thread и Queue.Queue , но это приводит к возникновению всех проблем с потоками, которые действительно отвлекают меня от реальной проблемы, которую я пытаюсь решить.

Я знаю, что могу запустить парсер SAX в отдельном процессе, но я считаю, что должен быть более простой способ получить данные. Здесь?

4 Solutions collect form web for “Как вернуть данные из анализатора SAX Python?”

Я думал, что я дам это как еще один ответ, потому что это совершенно другой подход.

Возможно, вы захотите проверить xml.etree.ElementTree.iterparse поскольку он, как представляется, делает больше, что вам нужно:

Парширует секцию XML в дереве элементов поэтапно и сообщает, что происходит с пользователем. source – это имя файла или файл, содержащий XML-данные. События – это список событий для отчета. Если опущено, сообщаются только события «конца». parser является необязательным экземпляром парсера. Если не задано, используется стандартный синтаксический анализатор XMLParser. Возвращает итератор, предоставляющий (event, elem) пары.

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

например:

 def find_spam(xml): for event, element in xml.etree.ElementTree.iterparse(xml): if element.tag == "spam": print("We found a spam!") # Potentially do something yield element 

Разница во многом зависит от того, что вы хотите. Подход итератора ElementTree связан с сбором данных, в то время как подход SAX – это скорее действие.

Дэвид Бэзли демонстрирует, как «давать» результаты от саксофона ContentHandler с помощью сопрограммы:

cosax.py :

 import xml.sax class EventHandler(xml.sax.ContentHandler): def __init__(self,target): self.target = target def startElement(self,name,attrs): self.target.send(('start',(name,attrs._attrs))) def characters(self,text): self.target.send(('text',text)) def endElement(self,name): self.target.send(('end',name)) def coroutine(func): def start(*args,**kwargs): cr = func(*args,**kwargs) cr.next() return cr return start # example use if __name__ == '__main__': @coroutine def printer(): while True: event = (yield) print event xml.sax.parse("allroutes.xml", EventHandler(printer())) 

Выше, каждый раз, self.target.send вызывается self.target.send , код внутри printer запускается начиная с event = (yield) . event присваивается аргументам self.target.send , а код в printer выполняется до достижения следующего (yield) , что-то вроде того, как работает генератор.

В то время как генератор, как правило, управляется for-loop , сопроцессор (например, printer ) управляется посылками.

Мое понимание – синтаксический анализатор SAX предназначен для выполнения работы, а не просто для передачи данных в цепочку продуктов питания.

например:

 class SpamExtractor(sax.ContentHandler): def __init__(self, canning_machine): self.canning_machine = canning_machine def startElement(self, name, attrs): if name == "spam": print("We found a spam!") self.canning_machine.can(name, attrs) 

В принципе существует три способа анализа XML:

  1. SAX- Approach: это реализация шаблона посетителя, идея состоит в том, что события переносятся в ваш код.
  2. StAX- Approach: вы нажимаете следующий элемент до тех пор, пока будете готовы (полезно для частичного разбора, то есть только для чтения SOAP-заголовка)
  3. DOM- Approach, где вы загружаете все в дерево в памяти

Кажется, вам нужно второе, но я не уверен, что это где-то в стандартной библиотеке.

  • OpenERP: создать новую запись, one2many many2one отношения
  • lxml xml разбор с тегами html внутри тегов xml
  • Лучший способ генерации xml?
  • Игнорирование ошибок XML в Python
  • Как получить необработанный XML обратно из lxml?
  • Исправление tostring () в LXML Python
  • Анализ XML в Python с использованием примера ElementTree
  • Чтение Excel xml в словарь
  • Python - лучший язык программирования в мире.