xml.dom.minidom — Минимальная реализация DOM
Исходный код: Lib/xml/dom/minidom.py
xml.dom.minidom — это минимальная реализация интерфейса Document Object Model с 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='', 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("<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там, где DOM-спецификация W3C разрешает иметь значение IDLnull. -
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.10/library/xml.dom.minidom.html