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, представляющий строку. Этот метод создаёт объект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.
20.7.1. Объекты DOM
Определение API DOM для Python приведено в документации модуля xml.dom. Этот раздел перечисляет различия между API и xml.dom.minidom.
-
Node.unlink() -
Разрыв внутренних ссылок в DOM, чтобы он был удалён сборщиком мусора в версиях Python без циклического GC. Даже когда циклический GC доступен, использование этого может освободить больше памяти раньше, поэтому вызов этого для объектов 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-заголовка.
-
Node.toxml(encoding=None) -
Возвращает строку или строку байтов, содержащую XML, представленный узлом DOM.
С явным аргументом encoding 1 результат — строка байтов в указанной кодировке. Без аргумента encoding результатом является строка Юникода, и XML-декларация в результирующей строке не указывает кодировку. Кодирование этой строки в кодировке, отличной от UTF-8, скорее всего, будет ошибочным, так как UTF-8 является кодировкой по умолчанию для XML.
-
Node.toprettyxml(indent="\t", newl="\n", encoding=None) -
Возвращает отформатированную версию документа. indent задаёт строку отступа и по умолчанию равна табуляции; newl задаёт строку, выводимую в конце каждой строки, и по умолчанию равна
\n.Аргумент encoding работает как соответствующий аргумент
toxml().
20.7.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)
20.7.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поддерживает как байты, так и строки, но обычно генерирует строки. Значения типа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:
DOMTimeStampDocumentTypeDOMImplementationCharacterDataCDATASectionNotationEntityEntityReferenceDocumentFragment
Большинство из них отражает информацию в 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–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/xml.dom.minidom.html