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, представляющий строку. Этот метод создает объект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.
-
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().
Пример 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 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:
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–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.7/library/xml.dom.minidom.html