Spec-Zone.ru › Python 2.7

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

Новая в версии 2.0.

Исходный код: 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[, bufsize]])

Возвращает Document из заданного ввода. filename_or_file может быть либо именем файла, либо объектом, подобным файлу. parser, если задан, должен быть объектом SAX2-парсера. Эта функция изменит обработчик документа парсера и активирует поддержку пространств имён; другая настройка парсера (например, установка решателя сущностей) должна быть выполнена заранее.

Если у вас есть XML в строке, вы можете использовать функцию parseString() вместо этого:

xml.dom.minidom.parseString(string[, parser])

Возвращает Document, представляющий строку. Этот метод создаёт объект StringIO для строки и передаёт его в parse().

Обе функции возвращают объект Document, представляющий содержимое документа.

То, что делают функции parse() и parseString(), это соединение XML-парсера с «строителем DOM», который может принимать события парсинга от любого SAX-парсера и преобразовывать их в дерево DOM. Названия функций, возможно, вводят в заблуждение, но их легко понять при изучении интерфейсов. Парсинг документа будет завершён до возврата этих функций; просто эти функции не предоставляют реализацию парсера сами по себе.

Вы также можете создать Document, вызвав метод на объекте «реализации DOM». Вы можете получить этот объект, вызвав функцию getDOMImplementation() в пакете xml.dom или модуле xml.dom.minidom. Использование реализации из модуля xml.dom.minidom всегда вернёт экземпляр Document из реализации minidom, в то время как версия из xml.dom может предоставить альтернативную реализацию (это вероятно, если у вас установлен пакет PyXML). После того, как у вас есть 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 без циклического сбора мусора. Даже когда циклический сбор мусора доступен, использование этого может раньше освободить большое количество памяти, поэтому вызов этого для объектов DOM, как только они больше не нужны, является хорошей практикой. Это нужно вызывать только для объекта Document, но может быть вызвано для дочерних узлов, чтобы отбросить дочерние узлы этого узла.

Node.writexml(writer, indent="", addindent="", newl="")

Запись XML в объект записи. Объект записи должен иметь метод write(), который соответствует интерфейсу объекта файла. Параметр indent — отступ текущего узла. Параметр addindent — приращение отступа для дочерних узлов текущего. Параметр newl определяет строку для завершения новых строк.

Для узла Document дополнительный параметр ключевого слова encoding может быть использован для указания поля кодировки заголовка XML.

Изменено в версии 2.1: Дополнительные параметры ключевых слов indent, addindent и newl были добавлены для поддержки красивого вывода.

Изменено в версии 2.3: Для узла Document дополнительный параметр ключевого слова encoding может быть использован для указания поля кодировки заголовка XML.

Node.toxml([encoding])

Возвращает XML, представляемый DOM, в виде строки.

Без аргумента заголовок XML не указывает кодировку, и результат — строка Unicode, если стандартная кодировка не может представить все символы в документе. Кодирование этой строки в кодировке, отличной от UTF-8, вероятно, неправильно, поскольку UTF-8 — это стандартная кодировка XML.

С явным аргументом encoding 1 результат — строка байтов в указанной кодировке. Рекомендуется всегда указывать этот аргумент. Чтобы избежать исключений UnicodeError в случае неудобочитаемых данных текста, аргумент encoding следует указывать как «utf-8».

Изменено в версии 2.3: аргумент encoding был добавлен; см. writexml().

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

Возвращает отформатированную версию документа. indent определяет строку отступа, по умолчанию это табуляция; newl определяет строку, выводимую в конце каждой строки, по умолчанию это \n.

Новая в версии 2.1.

Изменено в версии 2.3: аргумент encoding был добавлен; см. writexml().

Следующие стандартные методы DOM имеют особые соображения при использовании xml.dom.minidom:

Node.cloneNode(deep)

Хотя этот метод был присутствовал в версии xml.dom.minidom, поставляемой с Python 2.0, он был серьёзно сломан. Это было исправлено в последующих выпусках.

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 поддерживает байтовые или Unicode-строки, но обычно генерирует Unicode-строки. Значения типа 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. Начиная с Python 2.2, эти объекты предоставляют интерфейс, определенный в спецификации DOM, но в более ранних версиях Python они не поддерживают официальный API. Тем не менее, они намного «питоничнее», чем интерфейс, определенный в рекомендациях W3C.

Следующие интерфейсы не имеют реализации в xml.dom.minidom:

  • DOMTimeStamp
  • DocumentType (добавлено в Python 2.1)
  • DOMImplementation (добавлено в Python 2.1)
  • CharacterData
  • CDATASection
  • Notation
  • Entity
  • EntityReference
  • DocumentFragment

Большинство из них отражает информацию в XML-документе, которая не имеет общей полезности для большинства пользователей DOM.

Примечания

1

Строка кодировки, включенная в XML-выход, должна соответствовать соответствующим стандартам. Например, «UTF-8» допустимо, но «UTF8» — нет. См. 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/2.7/library/xml.dom.minidom.html

Spec-Zone.ru

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