Spec-Zone.ru › Python 3.11

xml.dom.minidom — Минимальная реализация DOM

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

xml.dom.minidom — это минимальная реализация интерфейса Document Object Model (DOM) с API, похожим на API других языков. Она предназначена быть проще, чем полная DOM, и значительно меньше по размеру. Пользователи, которые ещё не знакомы с DOM, должны рассмотреть использование модуля xml.etree.ElementTree для обработки XML вместо него.

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

Модуль xml.dom.minidom не защищён от вредоносно сконструированных данных. Если вам необходимо обработать недоверенные или неавторизованные данные, см. Уязвимости XML.

Приложения DOM обычно начинают с парсинга XML в DOM. С помощью xml.dom.minidom это делается с помощью функций парсинга:

from xml.dom.minidom import parse, parseString

dom1 = parse('c:\\temp\\mydata.xml')  # parse an XML file by name

datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource)  # parse an open file

dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')

Функция parse() может принимать либо имя файла, либо открытый объект файла.

xml.dom.minidom.parse(filename_or_file, parser=None, bufsize=None)

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

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

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

Возвращает объект Document, представляющий строку. Этот метод создаёт объект io.StringIO для строки и передаёт его функции parse().

Обе функции возвращают объект Document, представляющий содержимое документа.

То, что делают функции parse() и parseString(), — это подключение XML-парсера к «строителю DOM», который может принимать события парсинга от любого SAX-парсера и преобразовывать их в дерево DOM. Названия функций, возможно, вводят в заблуждение, но их легко понять, изучая интерфейсы. Парсинг документа будет завершён до возвращения этих функций; просто эти функции не предоставляют реализацию парсера сами по себе.

Вы также можете создать Document, вызвав метод на объекте «реализации DOM». Вы можете получить этот объект, вызвав функцию getDOMImplementation() в пакете xml.dom или модуле xml.dom.minidom. После того, как у вас есть Document, вы можете добавлять к нему дочерние узлы, чтобы заполнить DOM:

from xml.dom.minidom import getDOMImplementation

impl = getDOMImplementation()

newdoc = impl.createDocument(None, "some_tag", None)
top_element = newdoc.documentElement
text = newdoc.createTextNode('Some textual content.')
top_element.appendChild(text)

После получения объекта DOM-документа вы можете получить доступ к частям вашего XML-документа через его свойства и методы. Эти свойства определены в спецификации DOM. Главным свойством объекта документа является свойство documentElement. Оно даёт вам главный элемент в XML-документе: тот, который содержит все остальные. Вот пример программы:

dom3 = parseString("<myxml>Some data</myxml>")
assert dom3.documentElement.tagName == "myxml"

Когда вы закончите работу с деревом DOM, вы можете (по желанию) вызвать метод unlink(), чтобы стимулировать раннюю очистку теперь ненужных объектов. unlink() — это специфичное для xml.dom.minidom расширение API DOM, которое делает узел и его потомков по существу бесполезными. В противном случае сборщик мусора Python в конечном итоге позаботится об объектах в дереве.

См. также

Спецификация Document Object Model (DOM) Level 1

Рекомендация W3C для DOM, поддерживаемого xml.dom.minidom.

Объекты DOM

Определение API DOM для Python приведено в документации модуля xml.dom. В этом разделе перечислены различия между API и xml.dom.minidom.

Node.unlink()

Разрывает внутренние ссылки в DOM, чтобы его можно было собрать мусором в версиях Python без циклического сбора мусора. Даже когда циклический сбор мусора доступен, использование этого может сделать больше памяти доступной быстрее, поэтому вызов этого для объектов DOM сразу же после того, как они больше не нужны, является хорошей практикой. Это нужно вызывать только для объекта Document, но может быть вызвано для дочерних узлов, чтобы удалить потомков этого узла.

Вы можете избежать явного вызова этого метода, используя оператор with. Следующий код автоматически разорвёт ссылки для dom, когда блок with будет завершён:

with xml.dom.minidom.parse(datasource) as dom:
    ... # Work with dom.
Node.writexml(writer, indent='', addindent='', newl='', encoding=None, standalone=None)

Записывает XML в объект-письменного прибора. Письменный прибор получает текст, а не байты, как вход, он должен иметь метод write(), соответствующий интерфейсу объекта файла. Параметр indent — отступ текущего узла. Параметр addindent — инкремент отступа для дочерних узлов текущего. Параметр newl — строка, используемая для завершения новой строки.

Для узла Document дополнительный ключевой аргумент encoding может быть использован для указания поля кодировки заголовка XML.

Аналогично, явное указание аргумента standalone приводит к добавлению деклараций автономного документа в пролог XML-документа. Если значение установлено в True, standalone="yes" добавляется, в противном случае оно устанавливается в "no". Если аргумент не указан, декларация опускается из документа.

Изменено в версии 3.8: Метод writexml() теперь сохраняет порядок атрибутов, указанный пользователем.

Изменено в версии 3.9: Добавлен параметр standalone.

Node.toxml(encoding=None, standalone=None)

Возвращает строку или байтовую строку, содержащую XML, представленный узлом DOM.

С явным аргументом encoding 1 результат — байтовая строка в указанной кодировке. Без аргумента encoding результат — строка Unicode, а декларация XML в результирующей строке не указывает кодировку. Кодирование этой строки в кодировке, отличной от UTF-8, вероятно, неверно, так как UTF-8 — это кодировка по умолчанию для XML.

Аргумент standalone ведет себя точно так же, как в writexml().

Изменено в версии 3.8: Метод toxml() теперь сохраняет порядок атрибутов, указанный пользователем.

Изменено в версии 3.9: Добавлен параметр standalone.

Node.toprettyxml(indent='\t', newl='\n', encoding=None, standalone=None)

Возвращает отформатированную версию документа. indent задаёт строку отступа (по умолчанию — табуляция), newl задаёт строку, вставляемую в конце каждой строки (по умолчанию — «\n»).

Аргумент encoding ведет себя так же, как соответствующий аргумент в toxml().

Аргумент standalone ведет себя точно так же, как в writexml().

Изменено в версии 3.8: Метод toprettyxml() теперь сохраняет порядок атрибутов, указанный пользователем.

Изменено в версии 3.9: Добавлен параметр standalone.

Пример DOM

Эта программа-пример довольно реалистичный пример простой программы. В данном случае мы не используем максимальной гибкости DOM.

import xml.dom.minidom

document = """\
<slideshow>
<title>Demo slideshow</title>
<slide><title>Slide title</title>
<point>This is a demo</point>
<point>Of a program for processing slides</point>
</slide>

<slide><title>Another demo slide</title>
<point>It is important</point>
<point>To have more than</point>
<point>one slide</point>
</slide>
</slideshow>
"""

dom = xml.dom.minidom.parseString(document)

def getText(nodelist):
    rc = []
    for node in nodelist:
        if node.nodeType == node.TEXT_NODE:
            rc.append(node.data)
    return ''.join(rc)

def handleSlideshow(slideshow):
    print("<html>")
    handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])
    slides = slideshow.getElementsByTagName("slide")
    handleToc(slides)
    handleSlides(slides)
    print("</html>")

def handleSlides(slides):
    for slide in slides:
        handleSlide(slide)

def handleSlide(slide):
    handleSlideTitle(slide.getElementsByTagName("title")[0])
    handlePoints(slide.getElementsByTagName("point"))

def handleSlideshowTitle(title):
    print(f"<title>{getText(title.childNodes)}</title>")

def handleSlideTitle(title):
    print(f"<h2>{getText(title.childNodes)}</h2>")

def handlePoints(points):
    print("<ul>")
    for point in points:
        handlePoint(point)
    print("</ul>")

def handlePoint(point):
    print(f"<li>{getText(point.childNodes)}</li>")

def handleToc(slides):
    for slide in slides:
        title = slide.getElementsByTagName("title")[0]
        print(f"<p>{getText(title.childNodes)}</p>")

handleSlideshow(dom)

minidom и стандарт DOM

Модуль xml.dom.minidom по сути является совместимым с DOM 1.0 DOM с некоторыми функциями DOM 2 (в основном, функции пространства имён).

Использование интерфейса DOM в Python прямое. Применяются следующие правила сопоставления:

  • К интерфейсам обращаются через объекты экземпляров. Приложения не должны инициализировать классы самостоятельно; они должны использовать функции-создатели, доступные в объекте Document. Производные интерфейсы поддерживают все операции (и атрибуты) от базовых интерфейсов плюс любые новые операции.
  • Операции используются как методы. Поскольку DOM использует только параметры in, аргументы передаются в обычном порядке (слева направо). Дополнительных аргументов нет. void операции возвращают None.
  • Атрибуты IDL отображаются в атрибуты экземпляра. Для совместимости с сопоставлением языка OMG IDL для Python, атрибут foo также может быть получен через методы доступа _get_foo() и _set_foo(). readonly атрибуты не должны изменяться; это не проверяется во время выполнения.
  • Типы short int, unsigned int, unsigned long long и boolean все отображаются на объекты целых чисел Python.
  • Тип DOMString отображается на строки Python. xml.dom.minidom поддерживает как байты, так и строки, но обычно создаёт строки. Значения типа DOMString также могут быть None, где разрешено иметь значение IDL null в соответствии со спецификацией DOM от W3C.
  • const объявления отображаются на переменные в соответствующей области видимости (например, xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE); их нельзя изменять.
  • DOMException в настоящее время не поддерживается в xml.dom.minidom. Вместо этого xml.dom.minidom использует стандартные исключения Python, такие как TypeError и AttributeError.
  • Объекты NodeList реализуются с помощью встроенного типа списка Python. Эти объекты предоставляют интерфейс, определённый в спецификации DOM, но в более ранних версиях Python они не поддерживают официальный API. Однако они намного более «питонические», чем интерфейс, определённый в рекомендациях W3C.

Следующие интерфейсы не имеют реализации в xml.dom.minidom:

  • DOMTimeStamp
  • EntityReference

Большинство из них отражают информацию в XML-документе, которая не имеет общей полезности для большинства пользователей DOM.

Примечания

1

Имя кодировки, включённое в XML-вывод, должно соответствовать соответствующим стандартам. Например, «UTF-8» допустимо, но «UTF8» не допустимо в объявлении XML-документа, даже если Python принимает его как имя кодировки. См. https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl и https://www.iana.org/assignments/character-sets/character-sets.xhtml.

© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/xml.dom.minidom.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API