Spec-Zone.ru › Python 3.5

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, где разрешено иметь значение 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. Тем не менее, они гораздо более «pythonic», чем интерфейс, определённый в рекомендациях W3C.

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

  • DOMTimeStamp
  • DocumentType
  • DOMImplementation
  • CharacterData
  • CDATASection
  • Notation
  • Entity
  • EntityReference
  • DocumentFragment

Большинство из них отражает информацию в 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

Spec-Zone.ru

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