xml.dom.minidom — Минимальная реализация DOM
Новая в версии 2.0.
Исходный код: 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[, bufsize]]) -
Возвращает
Documentиз заданного ввода. filename_or_file может быть либо именем файла, либо объектом, подобным файлу. parser, если задан, должен быть объектом SAX2-парсера. Эта функция изменит обработчик документа парсера и активирует поддержку пространств имён; другая настройка парсера (например, установка решателя сущностей) должна быть выполнена заранее.
Если у вас есть XML в строке, вы можете использовать функцию parseString() вместо этого:
-
xml.dom.minidom.parseString(string[, parser]) -
Возвращает
Document, представляющий строку. Этот метод создаёт объектStringIOдля строки и передаёт его вparse().
Обе функции возвращают объект Document, представляющий содержимое документа.
То, что делают функции parse() и parseString(), это соединение XML-парсера с «строителем DOM», который может принимать события парсинга от любого SAX-парсера и преобразовывать их в дерево DOM. Названия функций, возможно, вводят в заблуждение, но их легко понять при изучении интерфейсов. Парсинг документа будет завершён до возврата этих функций; просто эти функции не предоставляют реализацию парсера сами по себе.
Вы также можете создать Document, вызвав метод на объекте «реализации DOM». Вы можете получить этот объект, вызвав функцию getDOMImplementation() в пакете xml.dom или модуле xml.dom.minidom. Использование реализации из модуля xml.dom.minidom всегда вернёт экземпляр Document из реализации minidom, в то время как версия из xml.dom может предоставить альтернативную реализацию (это вероятно, если у вас установлен пакет PyXML). После того, как у вас есть 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() — это расширение API DOM, специфичное для xml.dom.minidom, которое делает узел и его потомков по существу бесполезными. В противном случае сборщик мусора Python в конечном итоге позаботится об объектах в дереве.
См. также
- Спецификация Document Object Model (DOM) Level 1
-
Рекомендация W3C для DOM, поддерживаемого
xml.dom.minidom.
1. Объекты DOM
Определение API DOM для Python приводится в документации модуля xml.dom. В этом разделе перечислены отличия между API и xml.dom.minidom.
-
Node.unlink() -
Разрыв внутренних ссылок в DOM, чтобы он был собран мусором в версиях Python без циклического сбора мусора. Даже когда циклический сбор мусора доступен, использование этого может раньше освободить большое количество памяти, поэтому вызов этого для объектов DOM, как только они больше не нужны, является хорошей практикой. Это нужно вызывать только для объекта
Document, но может быть вызвано для дочерних узлов, чтобы отбросить дочерние узлы этого узла.
-
Node.writexml(writer, indent="", addindent="", newl="") -
Запись XML в объект записи. Объект записи должен иметь метод
write(), который соответствует интерфейсу объекта файла. Параметр indent — отступ текущего узла. Параметр addindent — приращение отступа для дочерних узлов текущего. Параметр newl определяет строку для завершения новых строк.Для узла
Documentдополнительный параметр ключевого слова encoding может быть использован для указания поля кодировки заголовка XML.Изменено в версии 2.1: Дополнительные параметры ключевых слов indent, addindent и newl были добавлены для поддержки красивого вывода.
Изменено в версии 2.3: Для узла
Documentдополнительный параметр ключевого слова encoding может быть использован для указания поля кодировки заголовка XML.
-
Node.toxml([encoding]) -
Возвращает XML, представляемый DOM, в виде строки.
Без аргумента заголовок XML не указывает кодировку, и результат — строка Unicode, если стандартная кодировка не может представить все символы в документе. Кодирование этой строки в кодировке, отличной от UTF-8, вероятно, неправильно, поскольку UTF-8 — это стандартная кодировка XML.
С явным аргументом encoding 1 результат — строка байтов в указанной кодировке. Рекомендуется всегда указывать этот аргумент. Чтобы избежать исключений
UnicodeErrorв случае неудобочитаемых данных текста, аргумент encoding следует указывать как «utf-8».Изменено в версии 2.3: аргумент encoding был добавлен; см.
writexml().
-
Node.toprettyxml(indent="\t", newl="\n", encoding=None) -
Возвращает отформатированную версию документа. indent определяет строку отступа, по умолчанию это табуляция; newl определяет строку, выводимую в конце каждой строки, по умолчанию это
\n.Новая в версии 2.1.
Изменено в версии 2.3: аргумент encoding был добавлен; см.
writexml().
Следующие стандартные методы DOM имеют особые соображения при использовании xml.dom.minidom:
-
Node.cloneNode(deep) -
Хотя этот метод был присутствовал в версии
xml.dom.minidom, поставляемой с Python 2.0, он был серьёзно сломан. Это было исправлено в последующих выпусках.
2. Пример 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)
3. 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поддерживает байтовые или Unicode-строки, но обычно генерирует Unicode-строки. Значения типа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. Начиная с Python 2.2, эти объекты предоставляют интерфейс, определенный в спецификации DOM, но в более ранних версиях Python они не поддерживают официальный API. Тем не менее, они намного «питоничнее», чем интерфейс, определенный в рекомендациях W3C.
Следующие интерфейсы не имеют реализации в xml.dom.minidom:
DOMTimeStamp-
DocumentType(добавлено в Python 2.1) -
DOMImplementation(добавлено в Python 2.1) CharacterDataCDATASectionNotationEntityEntityReferenceDocumentFragment
Большинство из них отражает информацию в XML-документе, которая не имеет общей полезности для большинства пользователей DOM.
Примечания
-
1 -
Строка кодировки, включенная в XML-выход, должна соответствовать соответствующим стандартам. Например, «UTF-8» допустимо, но «UTF8» — нет. См. https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl и https://www.iana.org/assignments/character-sets/character-sets.xhtml.
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/xml.dom.minidom.html