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, представляющий строку string. Этот метод создаёт объект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="") -
Записывает XML в объект записи. Запись получает текст, а не байты в качестве входных данных; она должна иметь метод
write(), который соответствует интерфейсу объекта файла. Параметр indent — отступ текущего узла. Параметр addindent — дополнительный отступ для дочерних узлов текущего. Параметр newl определяет строку для завершения новой строки.Для узла
Documentдополнительный ключевой аргумент encoding может использоваться для указания поля кодировки XML-заголовка.Изменено в версии 3.8: Метод
writexml()теперь сохраняет порядок атрибутов, указанный пользователем.
-
Node.toxml(encoding=None) -
Возвращает строку или строку байтов, содержащую XML, представленный узлом DOM.
С явным аргументом encoding 1 результатом является строка байтов в указанной кодировке. Без аргумента encoding результатом является строка Юникода, и XML-декларация в результирующей строке не указывает кодировку. Кодирование этой строки в кодировке, отличной от UTF-8, скорее всего, будет ошибочным, так как UTF-8 является кодировкой по умолчанию для XML.
Изменено в версии 3.8: Метод
toxml()теперь сохраняет порядок атрибутов, указанный пользователем.
-
Node.toprettyxml(indent="\t", newl="\n", encoding=None) -
Возвращает отформатированную версию документа. indent определяет строку отступа и по умолчанию является табуляцией; newl определяет строку, выводимую в конце каждой строки, и по умолчанию равна
\n.Аргумент encoding ведёт себя как соответствующий аргумент метода
toxml().Изменено в версии 3.8: Метод
toprettyxml()теперь сохраняет порядок атрибутов, указанный пользователем.
Пример 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("<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 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там, где допускается IDL-значениеnullсогласно спецификации 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. Тем не менее, они гораздо более «pythonic», чем интерфейс, определённый в рекомендациях 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–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.8/library/xml.dom.minidom.html