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, где разрешено иметь значение IDLnullв соответствии со спецификацией 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:
DOMTimeStampEntityReference
Большинство из них отражают информацию в 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