Я работаю над приложением, и мое задание просто состоит в том, чтобы разработать демонстрационный интерфейс Python для приложения. Приложение может предоставить основанный на XML документ, я могу добраться, документ через HTTP Получают метод, но проблемой является основанный на XML документ, бесконечно, что означает, что не будет никакого элемента конца. Я знаю, что документ должен быть обработан SAX, но как иметь дело с бесконечной проблемой? Какая-либо идея, пример кода?
Если документ никогда не получает закрывающий тег для элемента в документе, значит, это неправильно сформированный XML, который приведет к разрушению любого XML-парсер.
Тем не менее, использование Python SAX2 API могло бы показаться лучшим подходом, но вам нужно будет определить, какое исключение будет выдано отсутствующим закрывающим тегом, поймать его и обработать самостоятельно.
Добавлено
Предположим, вы получаете такой XML-документ:
<? xml version="1.0" ?>
<foo>
<bar>...</bar>
<bar>...</bar>
<bar>...</bar>
<bar>...</bar>
...
И вы никогда не получаете закрывающего
. В этом случае синтаксический анализатор SAX, который реагирует на элементы bar
, будет выдавать поток событий для startElement (bar)
и endElement (bar)
. Предположительно, вы соберете все данные между началом и концом, а затем обработаете все за один раз, как только увидите конечное событие.
Единственный способ остановить этот цикл - это внешнее действие: заранее определить количество элементов bar
для обработки или заранее определить количество времени, которое вы хотите посвятить получению бар
событий. Запустите синтаксический анализатор SAX в потоке, а затем завершите поток, когда вы достигнете своего предела. Вы хотите, чтобы ваш основной процесс спал, ожидая завершения потока sax-parser.
Если документ бесконечен, почему бы не добавить закрывающий тег (основного элемента) вручную перед его открытием в парсере? Я не знаю Python, но почему бы не добавить
в строку?
Взгляните на модуль xmlstream в jabberpy (также доступен по адресу twisted ):
xmlstream.py предоставляет простые функции для реализации Сетевые протоколы на основе XML-потоков. Используется как основа для jabber.py.
xmlstream.py управляет подключением к сети и синтаксическим анализом XML. потока. Когда полный «элемент протокола» (то есть полный дочерний элемент корня xmlstreams) анализируется дипатч вызывается с экземпляром этой структуры «Узел». Класс Node - это очень простой XML-DOM-подобный класс для манипулирование XML-документами или «элементами протокола» в этом кейс.
Я предполагаю, что ваш XML в основном представляет собой список одинаковых элементов XML, собранных под одним элементом-контейнером. Что-то вроде
<items>
<item>
<!-- content here -->
</item>
<item>
<!-- content here -->
</item>
<item>
<!-- content here -->
</item>
</items>
В SAX, когда ваш парсер получает событие end, вы можете разобрать завершенный элемент, очистить стек и передать элемент любому другому коду, который должен обрабатывать разобранные элементы.
def process(item) :
# App logic goes here
class ItemsHandler(xml.sax.handler.ContentHandler) :
# Omitting __init__, startElement, and characters methods
# to store data on a stack during processing
def endElement(self, name) :
if name == "item" :
# create item from stored data on stack
parsed_item = self.parse_item_from_stack()
process(parsed_item)
Если логика приложения достаточно сложна, вы захотите поместить разбор SAX в отдельный поток, чтобы не пропустить события.
Я не могу сразу предложить решение на Python, но дам вам подсказку.
Такой синтаксический анализ XML выполняется парсерами StAX . Проблема здесь в том, что SAX-парсер отправляет события, а StAX предоставляет интерфейс для извлечения событий. StAX в основном используется для частичного синтаксического анализа XML (синтаксический анализ только заголовков из сообщения SOAP), и, похоже, это ваш случай.
Я не встречал парсеров, подобных StAX, в стандартной библиотеке Python, но он определенно должен быть.
UPD: lxml (как оболочка для libxml2), похоже, имеет аналогичную функциональность .