Spec-Zone.ru › Python 3.14

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

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

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

Примечание

Если вам нужно анализировать недоверенные или не прошедшие проверку на подлинность данные, см. раздел Безопасность 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() — это расширение API DOM, специфичное для xml.dom.minidom, которое фактически делает узел и его потомков непригодными для использования. В противном случае объекты дерева со временем удалит сборщик мусора Python.

См. также

Спецификация объектной модели документа (DOM) уровня 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, если спецификация DOM W3C разрешает для них значение IDL null.
  • Объявления const сопоставляются с переменными в соответствующей области видимости (например, xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE); изменять их нельзя.
  • DOMException в настоящее время не поддерживается в xml.dom.minidom. Вместо этого xml.dom.minidom использует стандартные исключения Python, такие как TypeError и AttributeError.
  • Объекты NodeList реализованы с помощью встроенного типа list в 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 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/xml.dom.minidom.html

Spec-Zone.ru

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