Содержание страницы
xml.dom.minidom – Лёгкая реализация DOM¶xml.dom.minidom – Lightweight DOM implementation
xml.dom.minidom – это легковесная реализация интерфейса Document Object Model. Она задумана как более простая, чем полный DOM, и при этом значительно меньше по размеру.
Приложения DOM обычно начинаются с разбора XML в DOM. В xml.dom.minidom это делается с помощью функций parse:
from xml.dom.minidom import parse, parseString
dom1 = parse('c:\\temp\\mydata.xml') # разобрать XML-файл по имени
datasource = open('c:\\temp\\mydata.xml')
dom2 = parse(datasource) # разобрать открытый файл
dom3 = parseString('<myxml>Some data<empty/> some more data</myxml>')
Функция parse() может принимать либо имя файла, либо открытый файловый объект.
- xml.dom.minidom.parse(filename_or_file, parser)¶
- Возвращает 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 Implementation». Этот объект можно получить, вызвав функцию getDOMImplementation() в пакете xml.dom или модуле xml.dom.minidom. Использование реализации из модуля xml.dom.minidom всегда возвращает экземпляр Document из реализации minidom, тогда как версия из xml.dom может предоставить альтернативную реализацию (это вероятно, если установлен пакет PyXML package). Когда у вас есть 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 её следует очистить. Это необходимо, потому что некоторые версии Python не поддерживают сборку мусора для объектов, циклически ссылающихся друг на друга. Пока это ограничение не устранено во всех версиях Python, безопаснее всего писать код так, как если бы циклы не очищались.
Чтобы очистить DOM, следует вызвать его метод unlink():
dom1.unlink()
dom2.unlink()
dom3.unlink()
unlink() – это расширение DOM API, специфичное для xml.dom.minidom. После вызова unlink() на узле узел и его потомки становятся, по сути, бесполезными.
См. также
- Спецификация объектной модели документа (DOM) уровня 1
- Рекомендация W3C для DOM, поддерживаемого xml.dom.minidom.
Объекты DOM¶DOM Objects
Определение DOM API для Python приведено в документации модуля xml.dom. В этом разделе перечислены различия между API и xml.dom.minidom.
- Node.unlink()¶
- Разрывает внутренние ссылки в DOM, чтобы дерево могло быть собрано сборщиком мусора в версиях Python без циклического GC. Даже когда циклический GC доступен, его использование может освободить большие объёмы памяти раньше, поэтому вызов этого метода на DOM-объектах, как только они больше не нужны, является хорошей практикой. Этот метод нужно вызывать только на объекте Document, но можно вызывать и на дочерних узлах, чтобы удалить их потомков.
- Node.writexml(writer[, indent=""[, addindent=""[, newl=""[, encoding=""]]]])¶
Записывает XML в объект writer. Writer должен иметь метод write(), соответствующий интерфейсу файлового объекта. Параметр indent задаёт отступ текущего узла. Параметр addindent задаёт дополнительный отступ для подузлов текущего узла. Параметр newl задаёт строку, используемую для завершения строк.
Для узла Document можно использовать дополнительный именованный аргумент encoding, чтобы указать поле кодировки в заголовке XML.
- Node.toxml([encoding])¶
Возвращает XML-представление DOM в виде строки.
Если аргументы не переданы, заголовок XML не указывает кодировку, и результатом будет строка Unicode, если кодировка по умолчанию не может представить все символы документа. Кодирование этой строки в кодировке, отличной от UTF-8, скорее всего, некорректно, поскольку UTF-8 – это кодировка XML по умолчанию.
При явном указании аргумента encoding [1] результатом будет байтовая строка в указанной кодировке. Рекомендуется всегда указывать этот аргумент. Чтобы избежать исключений UnicodeError при наличии непредставимых текстовых данных, аргумент encoding следует задать как “utf-8”.
Пример DOM¶DOM Example
Эта примерная программа – довольно реалистичный пример простой программы. В данном конкретном случае мы не используем гибкость 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 = rc + node.data
return 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¶minidom and the DOM standard
Модуль xml.dom.minidom по сути является DOM, совместимым с 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, если это допускается спецификацией DOM от W3C для значения IDL null.
- Объявления 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
- DocumentType
- DOMImplementation
- CharacterData
- CDATASection
- Нотация
- Сущность
- Ссылка на сущность
- Фрагмент документа
Большинство из них отражают информацию в XML-документе, которая не представляет общей ценности для большинства пользователей DOM.
Сноски
| [1] | Строка кодировки, включённая в вывод XML, должна соответствовать соответствующим стандартам. Например, «UTF-8» допустимо, а «UTF8» – нет. См. http://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl и http://www.iana.org/assignments/character-sets . |