Spec-Zone.ru › Python 3.12

xml.dom.minidom — Минимальная реализация DOM

Исходный код: Lib/xml/dom/minidom.py

xml.dom.minidom — это минимальная реализация интерфейса Document Object Model (DOM), с 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() — это расширение API DOM, специфичное для xml.dom.minidom, которое делает узел и его потомков фактически бесполезными. В противном случае сборщик мусора 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 результатом является строка Юникод, и в результате XML-декларация не указывает кодировку. Кодирование этой строки в кодировке, отличной от UTF-8, вероятно, некорректно, поскольку UTF-8 является кодировкой по умолчанию для XML.

Аргумент standalone ведет себя точно так же, как в writexml().

Изменено в версии 3.8: Метод toxml() теперь сохраняет порядок атрибутов, указанный пользователем.

Изменено в версии 3.9: Параметр standalone был добавлен.

Node.toprettyxml(indent='\t', newl='\n', encoding=None, standalone=None)

Возвращает отформатированный (pretty-printed) документ. 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(f"<title>{getText(title.childNodes)}</title>")

def handleSlideTitle(title):
    print(f"<h2>{getText(title.childNodes)}</h2>")

def handlePoints(points):
    print("<ul>")
    for point in points:
        handlePoint(point)
    print("</ul>")

def handlePoint(point):
    print(f"<li>{getText(point.childNodes)}</li>")

def handleToc(slides):
    for slide in slides:
        title = slide.getElementsByTagName("title")[0]
        print(f"<p>{getText(title.childNodes)}</p>")

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–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/xml.dom.minidom.html

Spec-Zone.ru

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