xml.dom.minidom — Minimal DOM implementation

Вихідний код: Lib/xml/dom/minidom.py


xml.dom.minidom is a minimal implementation of the Document Object Model interface, with an API similar to that in other languages. It is intended to be simpler than the full DOM and also significantly smaller. Users who are not already proficient with the DOM should consider using the xml.etree.ElementTree module for their XML processing instead.

Примітка

If you need to parse untrusted or unauthenticated data, see XML security.

DOM applications typically start by parsing some XML into a DOM. With xml.dom.minidom, this is done through the parse functions:

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. Назви функцій, можливо, вводять в оману, але їх легко зрозуміти, вивчаючи інтерфейси. Розбір документа буде завершено до повернення цих функцій; просто ці функції самі по собі не забезпечують реалізацію аналізатора.

You can also create a Document by calling a method on a «DOM Implementation» object. You can get this object either by calling the getDOMImplementation() function in the xml.dom package or the xml.dom.minidom module. Once you have a Document, you can add child nodes to it to populate the 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"

When you are finished with a DOM tree, you may optionally call the unlink() method to encourage early cleanup of the now-unneeded objects. unlink() is an xml.dom.minidom-specific extension to the DOM API that renders the node and its descendants essentially useless. Otherwise, Python’s garbage collector will eventually take care of the objects in the tree.

Дивись також

Специфікація рівня 1 об’єктної моделі документа (DOM)

The W3C recommendation for the DOM supported by xml.dom.minidom.

Об’єкти DOM

The definition of the DOM API for Python is given as part of the xml.dom module documentation. This section lists the differences between the API and xml.dom.minidom.

Розбийте внутрішні посилання в DOM, щоб у версіях Python без циклічного збирання сміття було зібрано сміття. Навіть якщо циклічний GC доступний, використання цього може зробити великі обсяги пам’яті доступними раніше, тому виклик цього для об’єктів 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.

Similarly, explicitly stating the standalone argument causes the standalone document declarations to be added to the prologue of the XML document. If the value is set to True, standalone="yes" is added, otherwise it is set to "no". Not stating the argument will omit the declaration from the document.

Змінено в версії 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(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

The xml.dom.minidom module is essentially a DOM 1.0-compatible DOM with some DOM 2 features (primarily namespace features).

Використання інтерфейсу 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.

  • The type DOMString maps to Python strings. xml.dom.minidom supports either bytes or strings, but will normally produce strings. Values of type DOMString may also be None where allowed to have the IDL null value by the DOM specification from the W3C.

  • Оголошення const відображаються на змінні у відповідній області (наприклад, xml.dom.minidom.Node.PROCESSING_INSTRUCTION_NODE); їх не можна змінювати.

  • DOMException is currently not supported in xml.dom.minidom. Instead, xml.dom.minidom uses standard Python exceptions such as TypeError and AttributeError.

  • Об’єкти NodeList реалізовані за допомогою вбудованого типу списку Python. Ці об’єкти забезпечують інтерфейс, визначений у специфікації DOM, але в попередніх версіях Python вони не підтримують офіційний API. Однак вони набагато більш «пітонічні», ніж інтерфейс, визначений у рекомендаціях W3C.

The following interfaces have no implementation in xml.dom.minidom:

  • DOMTimeStamp

  • EntityReference

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

Виноски