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

Источник: Lib/xml/dom/pulldom.py


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

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

Модуль 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 может быть либо именем файла, либо файлоподобным объектом. парсер, если задан, должен быть объектом XMLReader. Эта функция изменит обработчик документов в парсере и активирует поддержку пространств имен; другие настройки парсера (например, установка распознавателя сущностей) должны быть сделаны заранее.

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

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

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

xml.dom.pulldom.default_bufsize

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

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

Объекты DOMEventStream

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

Изменено в версии 3.11: Поддержка метода __getitem__() была удалена.

getEvent()

Возвращает кортеж, содержащий событие и текущий узел в виде 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':
        # Following statement only prints '<p/>'
        print(node.toxml())
        doc.expandNode(node)
        # Following statement prints node with all its children '<p>Some text <div>and more</div></p>'
        print(node.toxml())
reset()