xml.dom.minidom — Минимальная реализация DOM
Исходный код: Lib/xml/dom/minidom.py
xml.dom.minidom представляет собой минимальную реализацию интерфейса Document Object Model, с 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() — это специфическое расширение 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 без циклического 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 результат — строка Unicode, и объявление XML в результирующей строке не указывает кодировку. Кодирование этой строки в кодировку, отличную от UTF-8, вероятно, неверно, так как UTF-8 является кодировкой по умолчанию для XML.
-
Node.toprettyxml(indent="", newl="", encoding="") -
Возвращает отформатированную версию документа. indent указывает строку отступа, по умолчанию — табуляция; newl указывает строку, выводимую в конце каждой строки, и по умолчанию —
\n.Аргумент encoding работает аналогично соответствующему аргументу
toxml().
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поддерживает байты или строки, но обычно генерирует строки. Значения типа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. Тем не менее, они гораздо более «pythonic», чем интерфейс, определённый в рекомендациях 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.5/library/xml.dom.minidom.html