xml.dom.pulldom — Поддержка построения частичных деревьев DOM

Исходный код: Lib/xml/dom/pulldom.py


Модуль xml.dom.pulldom обеспечивает «тяговый парсер», который также может быть запрошен для получения доступных DOM фрагментов документа, когда это необходимо. Основная концепция включает в себя извлечение «событий» из потока входящего XML и их обработку. В отличие от SAX, который также использует управляемую событиями модель обработки вместе с колбэки, пользователь парсер извлечения отвечает за явное извлечение событий из потока, закольцовывание этих событий до тех пор, пока обработка не будет завершена или не возникнет условие ошибки.

Предупреждение

Модуль xml.dom.pulldom не защищен от вредоносно созданных данных. Если требуется проанализировать ненадежные или неаутентифицированные данные, см. раздел Уязвимости XML.

Изменено в версии 3.7.1: SAX парсер больше не обрабатывает общие внешние объекты по умолчанию для повышения безопасности по умолчанию. Чтобы включить обработку внешних объектов, передайте пользовательский парсер в сущность:

from xml.dom.pulldom import parse
from xml.sax import make_parser
from xml.sax.handler import feature_external_ges

parser = make_parser()
parser.setFeature(feature_external_ges, True)
parse(filename, parser=parser)

Пример:

from xml.dom import pulldom

doc = pulldom.parse('sales_items.xml')
for event, node in doc:
    if event == pulldom.START_ELEMENT and node.tagName == 'item':
        if int(node.getAttribute('price')) > 50:
            doc.expandNode(node)
            print(node.toxml())

event является константой и может быть одной из:

  • START_ELEMENT
  • END_ELEMENT
  • COMMENT
  • START_DOCUMENT
  • END_DOCUMENT
  • CHARACTERS
  • PROCESSING_INSTRUCTION
  • IGNORABLE_WHITESPACE

node является объектом типа xml.dom.minidom.Document, xml.dom.minidom.Element или xml.dom.minidom.Text.

Поскольку документ рассматривается как «плоский» поток событий, «дерево» документа неявно пересекается, и требуемые элементы обнаруживаются независимо от их глубины в дереве. Другими словами, нет необходимости рассматривать иерархические вопросы, такие как рекурсивный поиск узлов документа, хотя, если контекст элементов были бы важны, нужно было бы либо поддерживать некоторые контекст-связанное состояние (т.е. запоминание того, где он находится в документе в любой данной точке) или использовать метод DOMEventStream.expandNode() и переключиться на обработку, связанную с DOM.

class xml.dom.pulldom.PullDom(documentFactory=None)

Подкласс xml.sax.handler.ContentHandler.

class xml.dom.pulldom.SAX2DOM(documentFactory=None)

Подкласс xml.sax.handler.ContentHandler.

xml.dom.pulldom.parse(stream_or_string, parser=None, bufsize=None)

Возвращает DOMEventStream из заданного ввода. stream_or_string может быть именем файла или похожим на файл объектом. parser, если он задан, должен быть XMLReader объектом. Эта функция изменяет обработчик документа парсер и активирует поддержку пространства имен; другая конфигурация парсер (например, установка распознавателя объекта) должна быть выполнена заранее.

Если в строка имеется XML, вместо него можно использовать функцию parseString():

xml.dom.pulldom.parseString(string, parser=None)

Возвращает DOMEventStream, представляющий string (Юникод).

xml.dom.pulldom.default_bufsize

Значение по умолчанию для bufsize параметра parse().

Перед вызовом значение можно изменить parse() этой переменной, и новый значение вступит в силу.

Объекты DOMEventStream

class xml.dom.pulldom.DOMEventStream(stream, parser, bufsize)

Не рекомендуется, начиная с версии 3.8: Поддержка протокол последовательности устарела.

getEvent()

Возвращает кортеж, содержащий event и текущий node, как xml.dom.minidom.Document если событие равно START_DOCUMENT, xml.dom.minidom.Element если событие равно START_ELEMENT или END_ELEMENT или xml.dom.minidom.Text если событие равно CHARACTERS. Текущий узел не содержит сведений о своих потомках, если не вызывается expandNode().

expandNode(node)

Расширяет все нижестоящие элементы node в node. Пример:

from xml.dom import pulldom

xml = '<html><title>Foo</title> <p>Some text <div>and more</div></p> </html>'
doc = pulldom.parseString(xml)
for event, node in doc:
    if event == pulldom.START_ELEMENT and node.tagName == 'p':
        # Следующая инструкция печатает только '<p/>'
        print(node.toxml())
        doc.expandNode(node)
        # Следующий оператор печатает узел со всеми его дочерними элементами '<p>Some text <div>and more</div></p>'
        print(node.toxml())
reset()