> **Источник:** https://python-all.ru/3.0/library/xml.dom.minidom.html
>
> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.

---

# `xml.dom.minidom` – Лёгкая реализация DOM

`xml.dom.minidom` – это легковесная реализация интерфейса Document Object Model. Она задумана как более простая, чем полный DOM, и при этом значительно меньше по размеру.

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

```python
from xml.dom.minidom import parse, parseString

dom1 = parse('c:\\temp\\mydata.xml') # разобрать XML-файл по имени

datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource)   # разобрать открытый файл

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

Функция [`parse()`](https://python-all.ru/3.0/library/xml.dom.minidom.html#xml.dom.minidom.parse) может принимать либо имя файла, либо открытый файловый объект.

#### `[xml.dom.minidom.parse]xml.dom.minidom.parse(filename_or_file, parser)`

Возвращает

`Document`

из переданных данных.

*filename\_or\_file*

может быть как именем файла, так и объектом, похожим на файл.

*parser*

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

Если XML находится в строке, можно использовать функцию [`parseString()`](https://python-all.ru/3.0/library/xml.dom.minidom.html#xml.dom.minidom.parseString) вместо этого:

#### `[xml.dom.minidom.parseString]xml.dom.minidom.parseString(string[, parser])`

Возвращает объект

`Document`

, представляющий

*строку*

. Этот метод создаёт объект

`StringIO`

для строки и передаёт его в

[`parse()`](https://python-all.ru/3.0/library/xml.dom.minidom.html#xml.dom.minidom.parse)

.

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

Функции [`parse()`](https://python-all.ru/3.0/library/xml.dom.minidom.html#xml.dom.minidom.parse) и [`parseString()`](https://python-all.ru/3.0/library/xml.dom.minidom.html#xml.dom.minidom.parseString) подключают XML-парсер к «построителю DOM», который может принимать события парсинга от любого SAX-парсера и преобразовывать их в DOM-дерево. Названия функций, возможно, вводят в заблуждение, но их легко понять при изучении интерфейсов. Разбор документа завершается до возврата из этих функций; просто сами функции не предоставляют реализацию парсера.

`Document` можно также создать, вызвав метод у объекта «DOM Implementation». Этот объект можно получить, вызвав функцию `getDOMImplementation()` в пакете [`xml.dom`](https://python-all.ru/3.0/library/xml.dom.html#module-xml.dom) или модуле `xml.dom.minidom`. Использование реализации из модуля `xml.dom.minidom` всегда возвращает экземпляр `Document` из реализации minidom, тогда как версия из [`xml.dom`](https://python-all.ru/3.0/library/xml.dom.html#module-xml.dom) может предоставить альтернативную реализацию (это вероятно, если установлен пакет [PyXML package](https://python-all.ru/3.0/library/xml.dom.minidom.html)). Когда у вас есть `Document`, можно добавлять к нему дочерние узлы, чтобы наполнить DOM:

```python
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-документа: тот, который содержит все остальные. Вот пример программы:

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

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

Чтобы очистить DOM, следует вызвать его метод `unlink()`:

```python
dom1.unlink()
dom2.unlink()
dom3.unlink()
```

`unlink()` – это расширение DOM API, специфичное для `xml.dom.minidom`. После вызова `unlink()` на узле узел и его потомки становятся, по сути, бесполезными.

> **См. также**
>
> **[Спецификация объектной модели документа (DOM) уровня 1](https://python-all.ru/3.0/library/xml.dom.minidom.html)**
>
> Рекомендация W3C для DOM, поддерживаемого
>
> `xml.dom.minidom`
>
> .

## Объекты DOM

Определение DOM API для Python приведено в документации модуля [`xml.dom`](https://python-all.ru/3.0/library/xml.dom.html#module-xml.dom). В этом разделе перечислены различия между API и `xml.dom.minidom`.

#### `[xml.dom.minidom.Node.unlink]Node.unlink()`

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

`Document`

, но можно вызывать и на дочерних узлах, чтобы удалить их потомков.

#### `[xml.dom.minidom.Node.writexml]Node.writexml(writer[, indent=""[, addindent=""[, newl=""[, encoding=""]]]])`

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

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

#### `[xml.dom.minidom.Node.toxml]Node.toxml([encoding])`

Возвращает XML-представление DOM в виде строки.

Если аргументы не переданы, заголовок XML не указывает кодировку, и результатом будет строка Unicode, если кодировка по умолчанию не может представить все символы документа. Кодирование этой строки в кодировке, отличной от UTF-8, скорее всего, некорректно, поскольку UTF-8 – это кодировка XML по умолчанию.

При явном указании аргумента *encoding* [\[1\]](https://python-all.ru/3.0/library/xml.dom.minidom.html#id3) результатом будет байтовая строка в указанной кодировке. Рекомендуется всегда указывать этот аргумент. Чтобы избежать исключений [`UnicodeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.UnicodeError) при наличии непредставимых текстовых данных, аргумент encoding следует задать как “utf-8”.

#### `[xml.dom.minidom.Node.toprettyxml]Node.toprettyxml([indent=""[, newl=""[, encoding=""]]])`

Возвращает красиво отформатированную версию документа. *indent* задаёт строку отступа; по умолчанию это табуляция. *newl* задаёт строку, добавляемую в конце каждой строки; по умолчанию это `\n`.

Также имеется аргумент *encoding*; см. [`toxml()`](https://python-all.ru/3.0/library/xml.dom.minidom.html#xml.dom.minidom.Node.toxml).

## Пример DOM

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

```python
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 = rc + node.data
    return 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("<title>%s</title>" % getText(title.childNodes))

def handleSlideTitle(title):
    print("<h2>%s</h2>" % getText(title.childNodes))

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

def handlePoint(point):
    print("<li>%s</li>" % getText(point.childNodes))

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

handleSlideshow(dom)
```

## minidom и стандарт DOM

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

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

- Интерфейсы доступны через объекты экземпляров. Приложения не должны создавать экземпляры классов напрямую; вместо этого следует использовать функции-создатели, доступные на объекте `Document`. Производные интерфейсы поддерживают все операции (и атрибуты) базовых интерфейсов, а также любые новые операции.
- Операции используются как методы. Поскольку DOM использует только параметры [`in`](https://python-all.ru/3.0/reference/expressions.html#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`](https://python-all.ru/3.0/library/exceptions.html#exceptions.TypeError) и [`AttributeError`](https://python-all.ru/3.0/library/exceptions.html#exceptions.AttributeError).
- Объекты `NodeList` реализованы с использованием встроенного типа списка Python. Эти объекты предоставляют интерфейс, определённый в спецификации DOM, но в более ранних версиях Python они не поддерживают официальный API. Однако они гораздо более «питоновские», чем интерфейс, определённый в рекомендациях W3C.

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

- `DOMTimeStamp`
- `DocumentType`
- `DOMImplementation`
- `CharacterData`
- `CDATASection`
- `Нотация`
- `Сущность`
- `Ссылка на сущность`
- `Фрагмент документа`

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

Сноски

| \[1\] | Строка кодировки, включённая в вывод XML, должна соответствовать соответствующим стандартам. Например, «UTF-8» допустимо, а «UTF8» – нет. См. [http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl](https://python-all.ru/3.0/library/xml.dom.minidom.html) и [http://www.iana.org/assignments/character-sets](https://python-all.ru/3.0/library/xml.dom.minidom.html) . |
| --- | --- |
