Для работы с готовым XML-документом нужно воспользоваться XML-анализаторами. Анализ XML-документа с порождением объекта класса Document происходит всего в одной строчке, с помощью функции parse(). Здесь стоит заметить, что кроме стандартного пакета xml можно поставить пакет PyXML или альтернативные коммерческие пакеты. Тем не менее, разработчики стараются придерживаться единого API, который продиктован стандартом DOM Level 2:
import xml.dom.minidom dom = xml.dom.minidom.parse("expression.xml")
dom.normalize()
def output_tree(node, level=0): if node.nodeType == node.TEXT_NODE: if node.nodeValue.strip(): print ". "*level, node.nodeValue.strip() else: # ELEMENT_NODE или DOCUMENT_NODE atts = node.attributes or {} att_string = ", ".join( ["%s=%s " % (k, v) for k, v in atts.items()]) print ". "*level, node.nodeName, att_string for child in node.childNodes: output_tree(child, level+1)
output_tree(dom)
В этом примере дерево выводится с помощью определенной функции output_tree(), которая принимает на входе узел и вызывается рекурсивно для всех вложенных узлов.
В результате получается примерно следующее:
#document . expression . . operation type=+ . . . operand . . . . 2 . . . operand . . . . operation type=* . . . . . operand . . . . . . 3 . . . . . operand . . . . . . 4
Здесь же применяется метод normalize() для того, чтобы все текстовые фрагменты были слиты воедино (в противном случае может следовать подряд несколько узлов с текстом).
Можно заметить, что даже в небольшом примере использовались атрибуты узлов: node.nodeType указывает тип узла, node.nodeValue применяется для доступа к данным, node.nodeName дает имя узла (соответствует названию тега), node.attributes дает доступ к атрибутам узла. node.childNodes применяется для доступа к дочерним узлам. Этих свойств достаточно, чтобы рекурсивно обойти дерево.
Все узлы являются экземплярами подклассов класса Node. Они могут быть следующих типов:
| ELEMENT_NODE | Элемент | createElement(tagname) |
| ATTRIBUTE_NODE | Атрибут | createAttribute(name) |
| TEXT_NODE | Текстовый узел | createTextNode(data) |
| CDATA_SECTION_NODE | Раздел CDATA | |
| ENTITY_REFERENCE_NODE | Ссылка на сущность | |
| ENTITY_NODE | Сущность | |
| PROCESSING_INSTRUCTION_NODE | Инструкция по обработке | createProcessingInstruction(target, data) |
| COMMENT_NODE | Комментарий | createComment(comment) |
| DOCUMENT_NODE | Документ | |
| DOCUMENT_TYPE_NODE | Тип документа | |
| DOCUMENT_FRAGMENT_NODE | Фрагмент документа | |
| NOTATION_NODE | Нотация |