Как вернуть данные из анализатора 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, где вы загружаете все в дерево в памяти

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

  • После xs: include при анализе XSD как XML с lxml в Python
  • Как сохранить таблицы строк в python-docx?
  • Как анализировать несколько XML (rss) с разных сайтов для одной обработки
  • Проблемы с кодировкой python's etree.tostring
  • Как создать SOAP-сообщение с помощью pysimplesoap?
  • Строки XML Unicode с объявлением кодировки не поддерживаются
  • Запуск памяти с использованием python ElementTree
  • Преобразование большого XML-файла в реляционную базу данных
  •  
    Interesting Posts for Van-Lav

    Для выполнения моей функции требуется отрицательное время. Что произошло в мире?

    python lxml с py2exe

    Как определить, является ли контейнер бесконечно рекурсивным и найти его самый маленький уникальный контейнер?

    Pandas Чтение CSV с разделителями строк с помощью регулярных выражений

    Индекс группы данных pandas dataframe за десятилетие

    Python argparse: "непризнанные аргументы"

    Добавить расширенные функции в текстовый виджет tkinter

    Как создать массив colormap из простого массива в matplotlib

    Настройка соотношения сторон 3D-графика

    Как скопировать wsgi.input, если я хочу обрабатывать данные POST более одного раза?

    SOAPpy – зарезервированное слово в списке названных параметров

    Оптимизация или ускорение чтения из .xy-файлов в excel

    Сельдерей: как проигнорировать задачу в аккорде или цепочке?

    Опубликовать в API Django rest framework, но всегда получать ошибку «Это поле обязательно»

    Выбор наиболее свободного текста из набора возможностей с помощью проверки грамматики (Python)

    Python - лучший язык программирования в мире.