xml.dom.minidom.md
1> **Источник:** https://python-all.ru/3.4/library/xml.dom.minidom.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 20.7. [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom) – минимальная реализация DOM89**Исходный код:** [Lib/xml/dom/minidom.py](https://python-all.ru/src/3.4/Lib/xml/dom/minidom.py)1011---1213[`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom) – это минимальная реализация интерфейса Document Object Model, с API, похожим на API в других языках. Он задуман как более простой, чем полный DOM, и значительно меньше. Пользователям, которые ещё не знакомы с DOM, стоит рассмотреть модуль [`xml.etree.ElementTree`](https://python-all.ru/3.4/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) для обработки XML вместо этого.1415> **Предупреждение**16>17> Модуль [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom) не является безопасным для злонамеренно сконструированных данных. Если требуется обрабатывать ненадёжные или неаутентифицированные данные, см. [*XML vulnerabilities*](https://python-all.ru/3.4/library/xml.html#xml-vulnerabilities).1819Приложения DOM обычно начинают с разбора некоторого XML в DOM. С помощью [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom) это делается через функции parse:2021```python22from xml.dom.minidom import parse, parseString2324dom1 = parse('c:\\temp\\mydata.xml') # разобрать XML-файл по имени2526datasource = open('c:\\temp\\mydata.xml')27dom2 = parse(datasource) # разобрать открытый файл2829dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')30```3132Функция [`parse()`](https://python-all.ru/3.4/library/xml.dom.minidom.html#xml.dom.minidom.parse) может принимать либо имя файла, либо открытый файловый объект.3334#### `xml.dom.minidom.parse(filename_or_file, parser=None, bufsize=None)`3536Возвращает `Document` из переданных данных. *filename\_or\_file* может быть как именем файла, так и объектом, похожим на файл. *parser*, если задан, должен быть объектом парсера SAX2. Эта функция изменит обработчик документа парсера и активирует поддержку пространств имён; другие настройки парсера (например, установка резолвера сущностей) должны быть выполнены заранее.3738Если XML находится в строке, можно использовать функцию [`parseString()`](https://python-all.ru/3.4/library/xml.dom.minidom.html#xml.dom.minidom.parseString) вместо этого:3940#### `xml.dom.minidom.parseString(string, parser=None)`4142Возвращает `Document`, представляющий строку *string*. Этот метод создаёт объект [`io.StringIO`](https://python-all.ru/3.4/library/io.html#io.StringIO) для строки и передаёт его в [`parse()`](https://python-all.ru/3.4/library/xml.dom.minidom.html#xml.dom.minidom.parse).4344Обе функции возвращают объект `Document`, представляющий содержимое документа.4546Функции [`parse()`](https://python-all.ru/3.4/library/xml.dom.minidom.html#xml.dom.minidom.parse) и [`parseString()`](https://python-all.ru/3.4/library/xml.dom.minidom.html#xml.dom.minidom.parseString) подключают XML-парсер к «построителю DOM», который может принимать события парсинга от любого SAX-парсера и преобразовывать их в DOM-дерево. Названия функций, возможно, вводят в заблуждение, но их легко понять при изучении интерфейсов. Разбор документа завершается до возврата из этих функций; просто сами функции не предоставляют реализацию парсера.4748Можно также создать `Document`, вызвав метод объекта «DOM Implementation». Этот объект можно получить, вызвав функцию `getDOMImplementation()` в пакете [`xml.dom`](https://python-all.ru/3.4/library/xml.dom.html#module-xml.dom) или в модуле [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom). Получив `Document`, можно добавлять к нему дочерние узлы для заполнения DOM:4950```python51from xml.dom.minidom import getDOMImplementation5253impl = getDOMImplementation()5455newdoc = impl.createDocument(None, "some_tag", None)56top_element = newdoc.documentElement57text = newdoc.createTextNode('Some textual content.')58top_element.appendChild(text)59```6061Получив объект DOM-документа, можно обращаться к частям XML-документа через его свойства и методы. Эти свойства определены в спецификации DOM. Основным свойством объекта документа является свойство `documentElement`. Оно даёт основной элемент XML-документа: тот, который содержит все остальные. Вот пример программы:6263```python64dom3 = parseString("<myxml>Some data</myxml>")65assert dom3.documentElement.tagName == "myxml"66```6768Когда работа с DOM-деревом завершена, можно по желанию вызвать метод `unlink()`, чтобы ускорить очистку уже не нужных объектов. `unlink()` является расширением DOM API, специфичным для [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom), которое делает узел и его потомков по сути бесполезными. В противном случае сборщик мусора Python в конечном итоге позаботится об объектах в дереве.6970> **См. также**71>72> **[Спецификация объектной модели документа (DOM) уровня 1](https://python-all.ru/3.4/library/xml.dom.minidom.html)**73>74> Рекомендация W3C для DOM, поддерживаемая75>76> [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom)77>78> .7980## 20.7.1. Объекты DOM8182Определение DOM API для Python приведено в документации модуля [`xml.dom`](https://python-all.ru/3.4/library/xml.dom.html#module-xml.dom). В этом разделе перечислены различия между этим API и [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom).8384#### `Node.unlink()`8586Разрывает внутренние ссылки в DOM, чтобы дерево могло быть собрано сборщиком мусора в версиях Python без циклического GC. Даже когда циклический GC доступен, его использование может освободить большие объёмы памяти раньше, поэтому вызов этого метода на DOM-объектах, как только они больше не нужны, является хорошей практикой. Этот метод нужно вызывать только на объекте `Document`, но можно вызывать и на дочерних узлах, чтобы удалить их потомков.8788Можно избежать явного вызова этого метода, используя оператор [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with). Следующий код автоматически вызовет unlink для *dom* при выходе из блока [`with`](https://python-all.ru/3.4/reference/compound_stmts.html#with):8990```python91with xml.dom.minidom.parse(datasource) as dom:92 ... # Работать с DOM.93```9495#### `Node.writexml(writer, indent="", addindent="", newl="")`9697Записывает XML в объект writer. Writer должен иметь метод `write()`, соответствующий интерфейсу файлового объекта. Параметр *indent* задаёт отступ текущего узла. Параметр *addindent* задаёт дополнительный отступ для подузлов текущего узла. Параметр *newl* задаёт строку, используемую для завершения строк.9899Для узла `Document` можно использовать дополнительный именованный аргумент *encoding* для указания поля кодировки в заголовке XML.100101#### `Node.toxml(encoding=None)`102103Возвращает строку или байтовую строку, содержащую XML, представленный узлом DOM.104105При явном указании аргумента *encoding* [\[1\]](https://python-all.ru/3.4/library/xml.dom.minidom.html#id3) результат представляет собой байтовую строку в указанной кодировке. Если аргумент *encoding* не указан, результатом является строка Unicode, и XML-объявление в результирующей строке не указывает кодировку. Кодирование этой строки в кодировку, отличную от UTF-8, скорее всего, некорректно, поскольку UTF-8 является кодировкой XML по умолчанию.106107#### `Node.toprettyxml(indent="", newl="", encoding="")`108109Возвращает красиво отформатированную версию документа. *indent* задаёт строку отступа; по умолчанию это табуляция. *newl* задаёт строку, добавляемую в конце каждой строки; по умолчанию это `\n`.110111Аргумент *encoding* ведёт себя так же, как соответствующий аргумент функции [`toxml()`](https://python-all.ru/3.4/library/xml.dom.minidom.html#xml.dom.minidom.Node.toxml).112113## 20.7.2. Пример DOM114115Эта примерная программа – довольно реалистичный пример простой программы. В данном конкретном случае мы не используем гибкость DOM в полной мере.116117```python118import xml.dom.minidom119120document = """\121<slideshow>122<title>Demo slideshow</title>123<slide><title>Slide title</title>124<point>This is a demo</point>125<point>Of a program for processing slides</point>126</slide>127128<slide><title>Another demo slide</title>129<point>It is important</point>130<point>To have more than</point>131<point>one slide</point>132</slide>133</slideshow>134"""135136dom = xml.dom.minidom.parseString(document)137138def getText(nodelist):139 rc = []140 for node in nodelist:141 if node.nodeType == node.TEXT_NODE:142 rc.append(node.data)143 return ''.join(rc)144145def handleSlideshow(slideshow):146 print("<html>")147 handleSlideshowTitle(slideshow.getElementsByTagName("title")[0])148 slides = slideshow.getElementsByTagName("slide")149 handleToc(slides)150 handleSlides(slides)151 print("</html>")152153def handleSlides(slides):154 for slide in slides:155 handleSlide(slide)156157def handleSlide(slide):158 handleSlideTitle(slide.getElementsByTagName("title")[0])159 handlePoints(slide.getElementsByTagName("point"))160161def handleSlideshowTitle(title):162 print("<title>%s</title>" % getText(title.childNodes))163164def handleSlideTitle(title):165 print("<h2>%s</h2>" % getText(title.childNodes))166167def handlePoints(points):168 print("<ul>")169 for point in points:170 handlePoint(point)171 print("</ul>")172173def handlePoint(point):174 print("<li>%s</li>" % getText(point.childNodes))175176def handleToc(slides):177 for slide in slides:178 title = slide.getElementsByTagName("title")[0]179 print("<p>%s</p>" % getText(title.childNodes))180181handleSlideshow(dom)182```183184## 20.7.3. minidom и стандарт DOM185186Модуль [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom), по сути, является DOM, совместимым с DOM 1.0, с некоторыми функциями DOM 2 (в основном связанными с пространствами имён).187188Использование интерфейса DOM в Python интуитивно понятно. Применяются следующие правила отображения:189190- Интерфейсы доступны через объекты экземпляров. Приложения не должны создавать экземпляры классов напрямую; вместо этого следует использовать функции-создатели, доступные на объекте `Document`. Производные интерфейсы поддерживают все операции (и атрибуты) базовых интерфейсов, а также любые новые операции.191- Операции используются как методы. Поскольку DOM использует только параметры [`in`](https://python-all.ru/3.4/reference/expressions.html#in), аргументы передаются в обычном порядке (слева направо). Необязательных аргументов нет. Операции `void` возвращают `None`.192- Атрибуты IDL отображаются на атрибуты экземпляров. Для совместимости с отображением языка OMG IDL для Python атрибут `foo` можно также получать через методы доступа `_get_foo()` и `_set_foo()`. Атрибуты `readonly` нельзя изменять; это не контролируется во время выполнения.193- Типы `short int`, `unsigned int`, `unsigned long long` и `boolean` отображаются на целочисленные объекты Python.194- Тип `DOMString` отображается на строки Python. [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom) поддерживает как байтовые строки, так и обычные строки, но обычно возвращает строки. Значения типа `DOMString` также могут быть `None`, если спецификация DOM от W3C допускает значение IDL `null`.195- Объявления `const` отображаются на переменные в соответствующей области видимости (например, `xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE`); их нельзя изменять.196- `DOMException` в настоящее время не поддерживается в [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom). Вместо этого [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom) использует стандартные исключения Python, такие как [`TypeError`](https://python-all.ru/3.4/library/exceptions.html#TypeError) и [`AttributeError`](https://python-all.ru/3.4/library/exceptions.html#AttributeError).197- Объекты `NodeList` реализованы с использованием встроенного типа списка Python. Эти объекты предоставляют интерфейс, определённый в спецификации DOM, но в более ранних версиях Python они не поддерживают официальный API. Однако они гораздо более «питоновские», чем интерфейс, определённый в рекомендациях W3C.198199Следующие интерфейсы не имеют реализации в [`xml.dom.minidom`](https://python-all.ru/3.4/library/xml.dom.minidom.html#module-xml.dom.minidom):200201- `DOMTimeStamp`202- `DocumentType`203- `DOMImplementation`204- `CharacterData`205- `CDATASection`206- `Notation`207- `Entity`208- `EntityReference`209- `DocumentFragment`210211Большинство из них отражают информацию в XML-документе, которая не представляет общей ценности для большинства пользователей DOM.212213Сноски214215| [\[1\]](https://python-all.ru/3.4/library/xml.dom.minidom.html#id1) | Имя кодировки, указанное в выводе XML, должно соответствовать соответствующим стандартам. Например, «UTF-8» допустимо, но «UTF8» недопустимо в объявлении XML-документа, несмотря на то что Python принимает его как имя кодировки. См. [http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl](https://python-all.ru/3.4/library/xml.dom.minidom.html) и [http://www.iana.org/assignments/character-sets/character-sets.xhtml](https://python-all.ru/3.4/library/xml.dom.minidom.html). |216| --- | --- |217