Spec-Zone.ru › Python 3.9

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, где разрешено иметь значение IDL null в соответствии со спецификацией 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:

  • DOMTimeStamp
  • EntityReference

Большинство из них отражают информацию в 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–2022 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.9/library/xml.dom.minidom.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API