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 результат — строка Юникода, и декларация 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.
Примечания
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/xml.dom.minidom.html