Spec-Zone.ru › Python 3.13

xml.etree.ElementTree — XML API ElementTree

Исходный код: Lib/xml/etree/ElementTree.py

Модуль xml.etree.ElementTree реализует простой и эффективный API для разбора и создания данных XML.

Изменено в версии 3.3: Этот модуль будет использовать быструю реализацию, когда она доступна.

Устарело с версии 3.3: Модуль xml.etree.cElementTree устарел.

Примечание

Если вам нужно анализировать недоверенные или неаутентифицированные данные, см. раздел Безопасность XML.

Учебное руководство

Это краткое руководство по использованию xml.etree.ElementTree (сокращённо ET). Его цель — продемонстрировать некоторые базовые компоненты и основные концепции модуля.

Дерево XML и элементы

XML — это изначально иерархический формат данных, и наиболее естественный способ его представления — дерево. ET содержит два класса для этой цели: ElementTree представляет весь XML-документ в виде дерева, а Element представляет отдельный узел в этом дереве. Операции со всем документом (чтение из файлов и запись в них) обычно выполняются на уровне ElementTree. Операции с отдельным элементом XML и его вложенными элементами выполняются на уровне Element.

Разбор XML

В этом разделе в качестве примера данных мы будем использовать вымышленный XML-документ country_data.xml:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

Мы можем импортировать эти данные, прочитав их из файла:

import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()

Или непосредственно из строки:

root = ET.fromstring(country_data_as_string)

fromstring() непосредственно разбирает XML из строки в объект Element, который является корневым элементом разобранного дерева. Другие функции разбора могут создавать объект ElementTree. Проверьте документацию, чтобы узнать наверняка.

Как Element, root имеет тег и словарь атрибутов:

>>> root.tag
'data'
>>> root.attrib
{}

У него также есть дочерние узлы, по которым можно итерироваться:

>>> for child in root:
...     print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

Дочерние элементы вложены друг в друга, и к отдельным дочерним узлам можно обращаться по индексу:

>>> root[0][1].text
'2008'

Примечание

Не все элементы входных данных XML попадут в разобранное дерево. В настоящее время этот модуль пропускает любые комментарии XML, инструкции обработки и объявления типа документа во входных данных. Тем не менее деревья, созданные с помощью API этого модуля, а не путём разбора текста XML, могут содержать комментарии и инструкции обработки; они будут включены при формировании выходных данных XML. Доступ к объявлению типа документа можно получить, передав пользовательский экземпляр TreeBuilder конструктору XMLParser.

Pull API для неблокирующего разбора

Большинство функций разбора, предоставляемых этим модулем, требуют чтения всего документа целиком до возврата результата. Можно использовать XMLParser и постепенно передавать ему данные, но это push API, который вызывает методы целевого объекта обратного вызова; такой подход слишком низкоуровневый и неудобный для большинства задач. Иногда пользователю нужно разбирать XML постепенно, без блокирующих операций, и при этом пользоваться удобством полностью сформированных объектов Element.

Самый мощный инструмент для этого — XMLPullParser. Для получения данных XML ему не требуется блокирующее чтение; вместо этого данные постепенно передаются вызовами XMLPullParser.feed(). Чтобы получить разобранные элементы XML, вызовите XMLPullParser.read_events(). Вот пример:

>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
...     print(event)
...     print(elem.tag, 'text=', elem.text)
...
end
mytag text= sometext more text

Очевидный вариант использования — приложения, работающие в неблокирующем режиме, когда данные XML поступают из сокета или постепенно считываются с какого-либо устройства хранения. В таких случаях блокирующее чтение недопустимо.

Из-за своей гибкости XMLPullParser может быть неудобен для более простых задач. Если вы не против блокировки приложения при чтении данных XML, но всё же хотите выполнять разбор постепенно, рассмотрите iterparse(). Он может быть полезен при чтении большого XML-документа, который не хочется целиком хранить в памяти.

Если требуется получать немедленную обратную связь через события, вызов метода XMLPullParser.flush() может помочь уменьшить задержку; обязательно ознакомьтесь с соответствующими примечаниями по безопасности.

Поиск нужных элементов

Element имеет несколько полезных методов, позволяющих рекурсивно перебирать всё поддерево под ним (его дочерние элементы, их дочерние элементы и так далее). Например, Element.iter():

>>> for neighbor in root.iter('neighbor'):
...     print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}

Element.findall() находит только элементы с заданным тегом, являющиеся непосредственными дочерними элементами текущего элемента. Element.find() находит первый дочерний элемент с заданным тегом, а Element.text предоставляет доступ к текстовому содержимому элемента. Element.get() предоставляет доступ к атрибутам элемента:

>>> for country in root.findall('country'):
...     rank = country.find('rank').text
...     name = country.get('name')
...     print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68

Более точное описание элементов для поиска возможно с помощью XPath.

Изменение XML-файла

ElementTree предоставляет простой способ создания XML-документов и их записи в файлы. Для этого предназначен метод ElementTree.write().

После создания объект Element можно изменять, напрямую меняя его поля (например, Element.text), добавляя и изменяя атрибуты (метод Element.set()), а также добавляя новые дочерние элементы (например, с помощью Element.append()).

Предположим, что мы хотим увеличить на единицу рейтинг каждой страны и добавить атрибут updated к элементу рейтинга:

>>> for rank in root.iter('rank'):
...     new_rank = int(rank.text) + 1
...     rank.text = str(new_rank)
...     rank.set('updated', 'yes')
...
>>> tree.write('output.xml')

Теперь наш XML выглядит так:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

Удалить элементы можно с помощью Element.remove(). Допустим, мы хотим удалить все страны с рейтингом выше 50:

>>> for country in root.findall('country'):
...     # using root.findall() to avoid removal during traversal
...     rank = int(country.find('rank').text)
...     if rank > 50:
...         root.remove(country)
...
>>> tree.write('output.xml')

Обратите внимание, что одновременное изменение данных во время итерации может привести к проблемам, как и при переборе и изменении списков или словарей Python. Поэтому в примере сначала с помощью root.findall() собираются все подходящие элементы, а уже затем выполняется итерация по списку найденных элементов.

Теперь наш XML выглядит так:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
</data>

Создание XML-документов

Функция SubElement() также предоставляет удобный способ создания новых вложенных элементов для заданного элемента:

>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>

Разбор XML с пространствами имён

Если входные данные XML содержат пространства имён, теги и атрибуты с префиксами вида prefix:sometag преобразуются в {uri}sometag, где префикс заменяется полным URI. Кроме того, если задано пространство имён по умолчанию, этот полный URI добавляется перед всеми тегами без префикса.

Вот пример XML с двумя пространствами имён: одно использует префикс «fictional», а другое является пространством имён по умолчанию:

<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
        xmlns="http://people.example.com">
    <actor>
        <name>John Cleese</name>
        <fictional:character>Lancelot</fictional:character>
        <fictional:character>Archie Leach</fictional:character>
    </actor>
    <actor>
        <name>Eric Idle</name>
        <fictional:character>Sir Robin</fictional:character>
        <fictional:character>Gunther</fictional:character>
        <fictional:character>Commander Clement</fictional:character>
    </actor>
</actors>

Один из способов поиска и изучения этого примера XML — вручную добавлять URI к каждому тегу или атрибуту в xpath для find() или findall():

root = fromstring(xml_text)
for actor in root.findall('{http://people.example.com}actor'):
    name = actor.find('{http://people.example.com}name')
    print(name.text)
    for char in actor.findall('{http://characters.example.com}character'):
        print(' |-->', char.text)

Лучший способ поиска в примере XML с пространствами имён — создать словарь с собственными префиксами и использовать их в функциях поиска:

ns = {'real_person': 'http://people.example.com',
      'role': 'http://characters.example.com'}

for actor in root.findall('real_person:actor', ns):
    name = actor.find('real_person:name', ns)
    print(name.text)
    for char in actor.findall('role:character', ns):
        print(' |-->', char.text)

Оба подхода выводят:

John Cleese
 |--> Lancelot
 |--> Archie Leach
Eric Idle
 |--> Sir Robin
 |--> Gunther
 |--> Commander Clement

Поддержка XPath

Этот модуль предоставляет ограниченную поддержку выражений XPath для поиска элементов в дереве. Цель — поддержать небольшое подмножество сокращённого синтаксиса; полноценный механизм XPath выходит за рамки возможностей модуля.

Пример

Вот пример, демонстрирующий некоторые возможности XPath в этом модуле. Мы будем использовать XML-документ countrydata из раздела Разбор XML:

import xml.etree.ElementTree as ET

root = ET.fromstring(countrydata)

# Top-level elements
root.findall(".")

# All 'neighbor' grand-children of 'country' children of the top-level
# elements
root.findall("./country/neighbor")

# Nodes with name='Singapore' that have a 'year' child
root.findall(".//year/..[@name='Singapore']")

# 'year' nodes that are children of nodes with name='Singapore'
root.findall(".//*[@name='Singapore']/year")

# All 'neighbor' nodes that are the second child of their parent
root.findall(".//neighbor[2]")

Для XML с пространствами имён используйте обычную запись с квалифицированным {namespace}tag:

# All dublin-core "title" tags in the document
root.findall(".//{http://purl.org/dc/elements/1.1/}title")

Поддерживаемый синтаксис XPath

Синтаксис

Значение

tag

Выбирает все дочерние элементы с заданным тегом. Например, spam выбирает все дочерние элементы с именем spam, а spam/egg выбирает всех внуков с именем egg среди всех дочерних элементов с именем spam. {namespace}* выбирает все теги в заданном пространстве имён, {*}spam выбирает теги с именем spam в любом пространстве имён (или без пространства имён), а {}* выбирает только теги, не принадлежащие пространству имён.

Изменено в версии 3.8: Добавлена поддержка подстановочных символов-звёздочек.

*

Выбирает все дочерние элементы, включая комментарии и инструкции обработки. Например, */egg выбирает всех внуков с именем egg.

.

Выбирает текущий узел. Это в основном полезно в начале пути, чтобы указать, что путь относительный.

//

Выбирает все вложенные элементы на всех уровнях под текущим элементом. Например, .//egg выбирает все элементы egg во всём дереве.

..

Выбирает родительский элемент. Возвращает None, если путь пытается перейти к предкам начального элемента (элемента, для которого был вызван find).

[@attrib]

Выбирает все элементы, имеющие заданный атрибут.

[@attrib='value']

Выбирает все элементы, у которых заданный атрибут имеет заданное значение. Значение не может содержать кавычки.

[@attrib!='value']

Выбирает все элементы, у которых заданный атрибут не имеет заданного значения. Значение не может содержать кавычки.

Добавлено в версии 3.10.

[tag]

Выбирает все элементы, у которых есть дочерний элемент с именем tag. Поддерживаются только непосредственные дочерние элементы.

[.='text']

Выбирает все элементы, полное текстовое содержимое которых, включая содержимое потомков, равно заданному text.

Добавлено в версии 3.7.

[.!='text']

Выбирает все элементы, полное текстовое содержимое которых, включая содержимое потомков, не равно заданному text.

Добавлено в версии 3.10.

[tag='text']

Выбирает все элементы, у которых есть дочерний элемент с именем tag и полное текстовое содержимое которого, включая содержимое потомков, равно заданному text.

[tag!='text']

Выбирает все элементы, у которых есть дочерний элемент с именем tag и полное текстовое содержимое которого, включая содержимое потомков, не равно заданному text.

Добавлено в версии 3.10.

[position]

Выбирает все элементы, находящиеся в заданной позиции. Позиция может быть целым числом (1 — первая позиция), выражением last() (последняя позиция) или позицией относительно последней (например, last()-1).

Предикатам (выражениям в квадратных скобках) должно предшествовать имя тега, звёздочка или другой предикат. Предикатам position должно предшествовать имя тега.

Справочник

Функции

xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)

Функция преобразования C14N 2.0.

Каноникализация — это способ нормализации вывода XML, позволяющий выполнять побайтовые сравнения и создавать цифровые подписи. Она ограничивает свободу действий сериализаторов XML и вместо этого формирует более строго заданное представление XML. Основные ограничения касаются расположения объявлений пространств имён, порядка атрибутов и незначащих пробелов.

Эта функция принимает в качестве входных данных строку XML (xml_data) или путь к файлу либо файловый объект (from_file), преобразует их в каноническую форму и записывает результат в файловый объект out (если он указан) либо возвращает его в виде текстовой строки. Выходной файл получает текст, а не байты. Поэтому его следует открывать в текстовом режиме с кодировкой utf-8.

Типичные варианты использования:

xml_data = "<root>...</root>"
print(canonicalize(xml_data))

with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:
    canonicalize(xml_data, out=out_file)

with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:
    canonicalize(from_file="inputfile.xml", out=out_file)

Параметры конфигурации options:

  • with_comments: установите значение true, чтобы включить комментарии (по умолчанию: false)
  • strip_text: установите значение true, чтобы удалять пробелы перед текстовым содержимым и после него

    (по умолчанию: false)

  • rewrite_prefixes: установите значение true, чтобы заменить префиксы пространств имён на «n{number}»

    (по умолчанию: false)

  • qname_aware_tags: набор имён тегов, учитывающих qname, в которых префиксы

    следует заменять в текстовом содержимом (по умолчанию: пустой набор)

  • qname_aware_attrs: набор имён атрибутов, учитывающих qname, в которых префиксы

    следует заменять в текстовом содержимом (по умолчанию: пустой набор)

  • exclude_attrs: набор имён атрибутов, которые не следует сериализовать
  • exclude_tags: набор имён тегов, которые не следует сериализовать

В приведённом выше списке параметров «набор» означает любую коллекцию или итерируемый объект строк; порядок не имеет значения.

Добавлено в версии 3.8.

xml.etree.ElementTree.Comment(text=None)

Фабрика элементов комментариев. Эта фабричная функция создаёт специальный элемент, который стандартный сериализатор сериализует как комментарий XML. Строка комментария может быть байтовой строкой или строкой Unicode. text — строка, содержащая текст комментария. Возвращает экземпляр элемента, представляющий комментарий.

Обратите внимание, что XMLParser пропускает комментарии во входных данных, не создавая для них объекты комментариев. ElementTree будет содержать узлы комментариев только в том случае, если они были вставлены в дерево с помощью одного из методов Element.

xml.etree.ElementTree.dump(elem)

Записывает дерево элементов или структуру элемента в sys.stdout. Эту функцию следует использовать только для отладки.

Точный формат вывода зависит от реализации. В этой версии результат записывается как обычный файл XML.

elem — это дерево элементов или отдельный элемент.

Изменено в версии 3.8: Функция dump() теперь сохраняет заданный пользователем порядок атрибутов.

xml.etree.ElementTree.fromstring(text, parser=None)

Разбирает раздел XML из строковой константы. То же, что и XML(). text — строка, содержащая данные XML. parser — необязательный экземпляр парсера. Если он не указан, используется стандартный парсер XMLParser. Возвращает экземпляр Element.

xml.etree.ElementTree.fromstringlist(sequence, parser=None)

Разбирает документ XML из последовательности фрагментов строк. sequence — список или другая последовательность, содержащая фрагменты данных XML. parser — необязательный экземпляр парсера. Если он не указан, используется стандартный парсер XMLParser. Возвращает экземпляр Element.

Добавлено в версии 3.2.

xml.etree.ElementTree.indent(tree, space=' ', level=0)

Добавляет пробелы в поддерево, чтобы визуально отформатировать дерево с отступами. Это можно использовать для создания красиво отформатированного вывода XML. tree может быть элементом Element или ElementTree. space — строка пробелов, которая будет вставляться на каждом уровне отступа; по умолчанию используются два пробела. Чтобы форматировать с отступами частичные поддеревья внутри уже отформатированного дерева, передайте начальный уровень отступа в параметре level.

Добавлено в версии 3.9.

xml.etree.ElementTree.iselement(element)

Проверяет, похож ли объект на корректный объект элемента. element — экземпляр элемента. Возвращает True, если это объект элемента.

xml.etree.ElementTree.iterparse(source, events=None, parser=None)

Постепенно разбирает раздел XML в дерево элементов и сообщает пользователю о ходе обработки. source — имя файла или файловый объект, содержащий данные XML. events — последовательность событий, о которых нужно сообщать. Поддерживаются события "start", "end", "comment", "pi", "start-ns" и "end-ns" (события «ns» используются для получения подробной информации о пространствах имён). Если events не задан, сообщаются только события "end". parser — необязательный экземпляр парсера. Если он не указан, используется стандартный парсер XMLParser. parser должен быть подклассом XMLParser и может использовать в качестве цели только стандартный TreeBuilder. Возвращает итератор, предоставляющий пары (event, elem); у него есть атрибут root, ссылающийся на корневой элемент результирующего дерева XML после полного чтения source. У итератора есть метод close(), который закрывает внутренний файловый объект, если source — имя файла.

Обратите внимание, что, хотя iterparse() строит дерево постепенно, он выполняет блокирующее чтение из source (или из указанного в нём файла). Поэтому он не подходит для приложений, в которых невозможно выполнять блокирующее чтение. Для полностью неблокирующего разбора см. XMLPullParser.

Примечание

iterparse() гарантирует лишь то, что при выдаче события «start» он обнаружил символ «>» открывающего тега, поэтому атрибуты определены, но содержимое атрибутов text и tail на этом этапе не определено. То же относится к дочерним элементам; они могут присутствовать, а могут и отсутствовать.

Если вам нужен полностью заполненный элемент, используйте события «end».

Устарело с версии 3.4: Аргумент parser.

Изменено в версии 3.8: Добавлены события comment и pi.

Изменено в версии 3.13: Добавлен метод close().

xml.etree.ElementTree.parse(source, parser=None)

Разбирает раздел XML в дерево элементов. source — имя файла или файловый объект, содержащий данные XML. parser — необязательный экземпляр парсера. Если он не указан, используется стандартный парсер XMLParser. Возвращает экземпляр ElementTree.

xml.etree.ElementTree.ProcessingInstruction(target, text=None)

Фабрика элементов PI. Эта фабричная функция создаёт специальный элемент, который будет сериализован как инструкция обработки XML. target — строка, содержащая цель PI. text — строка, содержащая содержимое PI, если она указана. Возвращает экземпляр элемента, представляющий инструкцию обработки.

Обратите внимание, что XMLParser пропускает инструкции обработки во входных данных, не создавая для них объекты PI. ElementTree будет содержать узлы инструкций обработки только в том случае, если они были вставлены в дерево с помощью одного из методов Element.

xml.etree.ElementTree.register_namespace(prefix, uri)

Регистрирует префикс пространства имён. Реестр является глобальным; существующие соответствия для заданного префикса или URI пространства имён будут удалены. prefix — префикс пространства имён. uri — URI пространства имён. Теги и атрибуты в этом пространстве имён будут сериализованы с указанным префиксом, если это возможно.

Добавлено в версии 3.2.

xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)

Фабрика подэлементов. Эта функция создаёт экземпляр элемента и добавляет его к существующему элементу.

Имя элемента, имена атрибутов и значения атрибутов могут быть байтовыми строками или строками Unicode. parent — родительский элемент. tag — имя подэлемента. attrib — необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные в виде именованных аргументов. Возвращает экземпляр элемента.

xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)

Создаёт строковое представление элемента XML, включая все подэлементы. element — экземпляр Element. encoding [1] — кодировка вывода (по умолчанию US-ASCII). Используйте encoding="unicode" для создания строки Unicode (в противном случае создаётся байтовая строка). method может быть "xml", "html" или "text" (по умолчанию "xml"). Параметры xml_declaration, default_namespace и short_empty_elements имеют тот же смысл, что и в ElementTree.write(). Возвращает (при необходимости закодированную) строку, содержащую данные XML.

Изменено в версии 3.4: Добавлен параметр short_empty_elements.

Изменено в версии 3.8: Добавлены параметры xml_declaration и default_namespace.

Изменено в версии 3.8: Функция tostring() теперь сохраняет заданный пользователем порядок атрибутов.

xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)

Создаёт строковое представление элемента XML, включая все подэлементы. element — экземпляр Element. encoding [1] — кодировка вывода (по умолчанию US-ASCII). Используйте encoding="unicode" для создания строки Unicode (в противном случае создаётся байтовая строка). method может быть "xml", "html" или "text" (по умолчанию "xml"). Параметры xml_declaration, default_namespace и short_empty_elements имеют тот же смысл, что и в ElementTree.write(). Возвращает список (при необходимости закодированных) строк, содержащих данные XML. Конкретная последовательность не гарантируется, за исключением того, что b"".join(tostringlist(element)) == tostring(element).

Добавлено в версии 3.2.

Изменено в версии 3.4: Добавлен параметр short_empty_elements.

Изменено в версии 3.8: Добавлены параметры xml_declaration и default_namespace.

Изменено в версии 3.8: Функция tostringlist() теперь сохраняет заданный пользователем порядок атрибутов.

xml.etree.ElementTree.XML(text, parser=None)

Разбирает раздел XML из строковой константы. Эту функцию можно использовать для встраивания «литералов XML» в код Python. text — строка, содержащая данные XML. parser — необязательный экземпляр парсера. Если он не указан, используется стандартный парсер XMLParser. Возвращает экземпляр Element.

xml.etree.ElementTree.XMLID(text, parser=None)

Разбирает раздел XML из строковой константы, а также возвращает словарь, сопоставляющий идентификаторы элементов с элементами. text — строка, содержащая данные XML. parser — необязательный экземпляр парсера. Если он не указан, используется стандартный парсер XMLParser. Возвращает кортеж, содержащий экземпляр Element и словарь.

Поддержка XInclude

Этот модуль предоставляет ограниченную поддержку директив XInclude с помощью вспомогательного модуля xml.etree.ElementInclude. Этот модуль можно использовать для вставки поддеревьев и текстовых строк в деревья элементов на основе информации из дерева.

Пример

Ниже приведён пример использования модуля XInclude. Чтобы включить документ XML в текущий документ, используйте элемент {http://www.w3.org/2001/XInclude}include, установите атрибут parse в значение "xml" и укажите включаемый документ с помощью атрибута href.

<?xml version="1.0"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
  <xi:include href="source.xml" parse="xml" />
</document>

По умолчанию атрибут href рассматривается как имя файла. Это поведение можно изменить с помощью пользовательских загрузчиков. Обратите также внимание, что стандартный вспомогательный модуль не поддерживает синтаксис XPointer.

Чтобы обработать этот файл, загрузите его обычным способом и передайте корневой элемент модулю xml.etree.ElementTree:

from xml.etree import ElementTree, ElementInclude

tree = ElementTree.parse("document.xml")
root = tree.getroot()

ElementInclude.include(root)

Модуль ElementInclude заменяет элемент {http://www.w3.org/2001/XInclude}include корневым элементом документа source.xml. Результат может выглядеть примерно так:

<document xmlns:xi="http://www.w3.org/2001/XInclude">
  <para>This is a paragraph.</para>
</document>

Если атрибут parse не указан, по умолчанию используется значение «xml». Атрибут href является обязательным.

Чтобы включить текстовый документ, используйте элемент {http://www.w3.org/2001/XInclude}include и установите атрибут parse в значение «text»:

<?xml version="1.0"?>
<document xmlns:xi="http://www.w3.org/2001/XInclude">
  Copyright (c) <xi:include href="year.txt" parse="text" />.
</document>

Результат может выглядеть примерно так:

<document xmlns:xi="http://www.w3.org/2001/XInclude">
  Copyright (c) 2003.
</document>

Справочник

Функции

xml.etree.ElementInclude.default_loader(href, parse, encoding=None)

Загрузчик по умолчанию. Этот загрузчик считывает включаемый ресурс с диска. href — это URL. parse задаёт режим разбора: «xml» или «text». encoding — необязательная кодировка текста. Если она не задана, используется utf-8. Возвращает расширенный ресурс. Если режим разбора — "xml", возвращается экземпляр Element. Если режим разбора — "text", возвращается строка. Если загрузчику не удаётся выполнить загрузку, он может вернуть None или вызвать исключение.

xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)

Эта функция на месте раскрывает директивы XInclude в дереве, на которое указывает elem. elem — это либо корневой Element, либо экземпляр ElementTree, в котором нужно найти такой элемент. loader — необязательный загрузчик ресурсов. Если он не указан, используется default_loader(). Если он указан, это должен быть вызываемый объект, реализующий тот же интерфейс, что и default_loader(). base_url — базовый URL исходного файла, используемый для разрешения относительных ссылок на включаемые файлы. max_depth — максимальное количество рекурсивных включений. Ограничение введено для снижения риска чрезмерного разрастания из-за вредоносного содержимого. Передайте None, чтобы отключить ограничение.

Изменено в версии 3.9: Добавлены параметры base_url и max_depth.

Объекты Element

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)

Класс Element. Этот класс определяет интерфейс Element и предоставляет его эталонную реализацию.

Имя элемента, имена атрибутов и значения атрибутов могут быть как байтовыми строками, так и строками Unicode. tag — имя элемента. attrib — необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, переданные как именованные аргументы.

tag

Строка, указывающая, какой тип данных представляет этот элемент (другими словами, тип элемента).

text
tail

Эти атрибуты можно использовать для хранения дополнительных данных, связанных с элементом. Обычно их значениями являются строки, но они также могут быть любыми объектами, специфичными для приложения. Если элемент создан из XML-файла, атрибут text содержит либо текст между открывающим тегом элемента и его первым дочерним элементом или закрывающим тегом, либо None, а атрибут tail содержит либо текст между закрывающим тегом элемента и следующим тегом, либо None. Для XML-данных

<a><b>1<c>2<d/>3</c></b>4</a>

элемент a имеет None для атрибутов text и tail, элемент b имеет text "1" и tail "4", элемент c имеет text "2" и tail None, а элемент d имеет text None и tail "3".

Чтобы собрать внутренний текст элемента, см. itertext(), например "".join(element.itertext()).

Приложения могут хранить в этих атрибутах произвольные объекты.

attrib

Словарь, содержащий атрибуты элемента. Обратите внимание: хотя значение attrib всегда является настоящим изменяемым словарём Python, реализация ElementTree может использовать другое внутреннее представление и создавать словарь только по запросу. Чтобы воспользоваться такими реализациями, по возможности используйте приведённые ниже методы словаря.

Следующие методы, подобные методам словаря, работают с атрибутами элемента.

clear()

Сбрасывает элемент. Эта функция удаляет все дочерние элементы, очищает все атрибуты и устанавливает для атрибутов text и tail значение None.

get(key, default=None)

Получает атрибут элемента с именем key.

Возвращает значение атрибута или default, если атрибут не найден.

items()

Возвращает атрибуты элемента в виде последовательности пар (имя, значение). Атрибуты возвращаются в произвольном порядке.

keys()

Возвращает имена атрибутов элемента в виде списка. Имена возвращаются в произвольном порядке.

set(key, value)

Устанавливает для атрибута key элемента значение value.

Следующие методы работают с дочерними элементами элемента.

append(subelement)

Добавляет элемент subelement в конец внутреннего списка дочерних элементов этого элемента. Вызывает TypeError, если subelement не является Element.

extend(subelements)

Добавляет дочерние элементы subelements из итерируемого объекта элементов. Вызывает TypeError, если дочерний элемент не является Element.

Добавлено в версии 3.2.

find(match, namespaces=None)

Находит первый дочерний элемент, соответствующий match. match может быть именем тега или путём. Возвращает экземпляр элемента или None. namespaces — необязательное соответствие префиксов пространств имён полным именам. Передайте '' в качестве префикса, чтобы поместить все имена тегов без префикса в выражении в указанное пространство имён.

findall(match, namespaces=None)

Находит все подходящие дочерние элементы по имени тега или пути. Возвращает список всех подходящих элементов в порядке документа. namespaces — необязательное соответствие префиксов пространств имён полным именам. Передайте '' в качестве префикса, чтобы поместить все имена тегов без префикса в выражении в указанное пространство имён.

findtext(match, default=None, namespaces=None)

Находит текст первого дочернего элемента, соответствующего match. match может быть именем тега или путём. Возвращает текстовое содержимое первого подходящего элемента или default, если элемент не найден. Обратите внимание: если у подходящего элемента нет текстового содержимого, возвращается пустая строка. namespaces — необязательное соответствие префиксов пространств имён полным именам. Передайте '' в качестве префикса, чтобы поместить все имена тегов без префикса в выражении в указанное пространство имён.

insert(index, subelement)

Вставляет элемент subelement в указанную позицию этого элемента. Вызывает TypeError, если subelement не является Element.

iter(tag=None)

Создаёт древовидный итератор с текущим элементом в качестве корня. Итератор проходит по этому элементу и всем его потомкам в порядке документа (сначала в глубину). Если tag не равен None или '*', итератор возвращает только элементы, тег которых совпадает с tag. Если во время итерации структура дерева изменяется, результат не определён.

Добавлено в версии 3.2.

iterfind(match, namespaces=None)

Находит все подходящие дочерние элементы по имени тега или пути. Возвращает итерируемый объект, выдающий все подходящие элементы в порядке документа. namespaces — необязательное соответствие префиксов пространств имён полным именам.

Добавлено в версии 3.2.

itertext()

Создаёт итератор текста. Итератор проходит по этому элементу и всем его дочерним элементам в порядке документа и возвращает весь внутренний текст.

Добавлено в версии 3.2.

makeelement(tag, attrib)

Создаёт новый объект элемента того же типа, что и этот элемент. Не вызывайте этот метод, используйте вместо него фабричную функцию SubElement().

remove(subelement)

Удаляет subelement из элемента. В отличие от методов find*, этот метод сравнивает элементы по идентичности экземпляров, а не по значению тега или содержимому.

Объекты Element также поддерживают следующие методы последовательностей для работы с дочерними элементами: __delitem__(), __getitem__(), __setitem__(), __len__().

Внимание: элементы без дочерних элементов при проверке истинности считаются False. В будущей версии Python все элементы будут считаться True независимо от наличия дочерних элементов. Вместо этого предпочтительно использовать явные проверки len(elem) или elem is not None:

element = root.find('foo')

if not element:  # careful!
    print("element not found, or element has no subelements")

if element is None:
    print("element not found")

Изменено в версии 3.12: Проверка логического значения элемента вызывает DeprecationWarning.

До Python 3.8 порядок сериализации XML-атрибутов элементов искусственно делали предсказуемым, сортируя атрибуты по именам. Благодаря гарантированному теперь порядку словарей в Python 3.8 эту произвольную перестановку убрали, чтобы сохранять порядок, в котором атрибуты изначально разбирались или создавались пользовательским кодом.

В целом пользовательскому коду следует избегать зависимости от конкретного порядка атрибутов, поскольку информационный набор XML явно исключает порядок атрибутов из числа носителей информации. Код должен быть готов обрабатывать входные данные с любым порядком атрибутов. Если требуется детерминированный вывод XML, например для криптографической подписи или наборов тестовых данных, доступна каноническая сериализация с помощью функции canonicalize().

Если канонический вывод неприменим, но при выводе всё же желателен определённый порядок атрибутов, следует создавать атрибуты сразу в нужном порядке, чтобы читатели кода не сталкивались с неожиданным несоответствием. Если это сложно сделать, перед сериализацией можно применить следующий способ, чтобы задать порядок независимо от создания элемента:

def reorder_attributes(root):
    for el in root.iter():
        attrib = el.attrib
        if len(attrib) > 1:
            # adjust attribute order, e.g. by sorting
            attribs = sorted(attrib.items())
            attrib.clear()
            attrib.update(attribs)

Объекты ElementTree

class xml.etree.ElementTree.ElementTree(element=None, file=None)

Класс-обёртка ElementTree. Этот класс представляет всю иерархию элементов и предоставляет дополнительные средства для сериализации стандартного XML и обратно.

element — корневой элемент. Если задан file, дерево инициализируется содержимым XML-файла.

_setroot(element)

Заменяет корневой элемент этого дерева. Текущее содержимое дерева удаляется и заменяется заданным элементом. Используйте с осторожностью. element — экземпляр элемента.

find(match, namespaces=None)

То же, что и Element.find(), начиная с корня дерева.

findall(match, namespaces=None)

То же, что и Element.findall(), начиная с корня дерева.

findtext(match, default=None, namespaces=None)

То же, что и Element.findtext(), начиная с корня дерева.

getroot()

Возвращает корневой элемент этого дерева.

iter(tag=None)

Создаёт и возвращает итератор по дереву для корневого элемента. Итератор проходит по всем элементам этого дерева в порядке секций. tag — тег для поиска (по умолчанию возвращаются все элементы).

iterfind(match, namespaces=None)

То же, что и Element.iterfind(), начиная с корня дерева.

Добавлено в версии 3.2.

parse(source, parser=None)

Загружает внешний раздел XML в это дерево элементов. source — имя файла или файловый объект. parser — необязательный экземпляр синтаксического анализатора. Если он не задан, используется стандартный синтаксический анализатор XMLParser. Возвращает корневой элемент раздела.

write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml', *, short_empty_elements=True)

Записывает дерево элементов в файл в формате XML. file — имя файла или открытый для записи файловый объект. encoding [1] — кодировка вывода (по умолчанию US-ASCII). Параметр xml_declaration определяет, нужно ли добавлять в файл объявление XML. Используйте False, чтобы никогда его не добавлять, True — чтобы добавлять всегда, None — чтобы добавлять только при кодировке, отличной от US-ASCII, UTF-8 или Unicode (по умолчанию None). default_namespace задаёт пространство имён XML по умолчанию (для «xmlns»). method — это "xml", "html" или "text" (по умолчанию "xml"). Параметр short_empty_elements, задаваемый только по имени, управляет форматированием элементов без содержимого. Если задано True (значение по умолчанию), они выводятся в виде одного самозакрывающегося тега, в противном случае — в виде пары открывающего и закрывающего тегов.

Результат — это либо строка (str), либо двоичные данные (bytes). Это определяется аргументом encoding. Если encoding равен "unicode", результатом будет строка; в противном случае — двоичные данные. Обратите внимание, что тип результата может не совпадать с типом file, если это открытый файловый объект. Убедитесь, что не пытаетесь записать строку в двоичный поток и наоборот.

Изменено в версии 3.4: Добавлен параметр short_empty_elements.

Изменено в версии 3.8: Метод write() теперь сохраняет заданный пользователем порядок атрибутов.

Вот XML-файл, который будет изменяться:

<html>
    <head>
        <title>Example page</title>
    </head>
    <body>
        <p>Moved to <a href="http://example.org/">example.org</a>
        or <a href="http://example.com/">example.com</a>.</p>
    </body>
</html>

Пример изменения атрибута «target» у каждой ссылки в первом абзаце:

>>> from xml.etree.ElementTree import ElementTree
>>> tree = ElementTree()
>>> tree.parse("index.xhtml")
<Element 'html' at 0xb77e6fac>
>>> p = tree.find("body/p")     # Finds first occurrence of tag p in body
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a"))   # Returns list of all links
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in links:             # Iterates through all found links
...     i.attrib["target"] = "blank"
...
>>> tree.write("output.xhtml")

Объекты QName

class xml.etree.ElementTree.QName(text_or_uri, tag=None)

Обёртка QName. Её можно использовать для обёртывания значения атрибута QName, чтобы обеспечить корректную обработку пространств имён при выводе. text_or_uri — строка со значением QName в формате {uri}local или, если задан аргумент tag, часть URI значения QName. Если задан tag, первый аргумент интерпретируется как URI, а этот аргумент — как локальное имя. Экземпляры QName являются непрозрачными.

Объекты TreeBuilder

class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)

Универсальный построитель структуры элементов. Этот построитель преобразует последовательность вызовов методов start, data, end, comment и pi в корректную структуру элементов. Этот класс можно использовать для создания структуры элементов с помощью пользовательского синтаксического анализатора XML или анализатора для другого формата, похожего на XML.

Если задан element_factory, он должен быть вызываемым объектом, принимающим два позиционных аргумента: тег и словарь атрибутов. Предполагается, что он возвращает новый экземпляр элемента.

Если заданы функции comment_factory и pi_factory, они должны работать подобно функциям Comment() и ProcessingInstruction(), создавая комментарии и инструкции обработки. Если они не заданы, используются фабрики по умолчанию. Если значение insert_comments и/или insert_pis равно true, комментарии и инструкции обработки добавляются в дерево, если встречаются внутри корневого элемента (но не за его пределами).

close()

Сбрасывает буферы построителя и возвращает верхнеуровневый элемент документа. Возвращает экземпляр Element.

data(data)

Добавляет текст к текущему элементу. data — строка. Это должна быть байтовая строка или строка Unicode.

end(tag)

Закрывает текущий элемент. tag — имя элемента. Возвращает закрытый элемент.

start(tag, attrs)

Открывает новый элемент. tag — имя элемента. attrs — словарь, содержащий атрибуты элемента. Возвращает открытый элемент.

comment(text)

Создаёт комментарий с заданным текстом text. Если insert_comments имеет значение true, комментарий также добавляется в дерево.

Добавлено в версии 3.8.

pi(target, text)

Создаёт инструкцию обработки с заданным именем target и текстом text. Если insert_pis имеет значение true, инструкция также добавляется в дерево.

Добавлено в версии 3.8.

Кроме того, пользовательский объект TreeBuilder может предоставлять следующие методы:

doctype(name, pubid, system)

Обрабатывает объявление doctype. name — имя doctype. pubid — публичный идентификатор. system — системный идентификатор. Этот метод отсутствует в классе TreeBuilder по умолчанию.

Добавлено в версии 3.2.

start_ns(prefix, uri)

Вызывается каждый раз, когда синтаксический анализатор встречает объявление нового пространства имён, перед обратным вызовом start() для открывающего элемента, в котором оно объявлено. prefix равен '' для пространства имён по умолчанию; в противном случае это имя объявленного префикса пространства имён. uri — URI пространства имён.

Добавлено в версии 3.8.

end_ns(prefix)

Вызывается после обратного вызова end() для элемента, в котором объявлено соответствие префикса пространству имён; передаётся имя префикса prefix, область видимости которого завершилась.

Добавлено в версии 3.8.

class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None)

Записывающее устройство C14N 2.0. Аргументы те же, что и у функции canonicalize(). Этот класс не строит дерево, а преобразует события обратных вызовов непосредственно в сериализованную форму с помощью функции write.

Добавлено в версии 3.8.

Объекты XMLParser

class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)

Этот класс является низкоуровневым строительным блоком модуля. Он использует xml.parsers.expat для эффективного разбора XML на основе событий. В него можно постепенно передавать данные XML с помощью метода feed(), а события разбора преобразуются в push API — путем вызова обратных вызовов у объекта target. Если target не указан, используется стандартный TreeBuilder. Если задана encoding [1], это значение переопределяет кодировку, указанную в файле XML.

Изменено в версии 3.8: Теперь параметры являются только именованными. Аргумент html больше не поддерживается.

close()

Завершает передачу данных парсеру. Возвращает результат вызова метода close() объекта target, переданного при создании; по умолчанию это корневой элемент документа.

feed(data)

Передает данные парсеру. data — это закодированные данные.

flush()

Запускает разбор ранее переданных, но еще не обработанных данных, что позволяет получать обратную связь быстрее, особенно при использовании Expat >=2.6.0. Реализация flush() временно отключает отложенный повторный разбор в Expat (если он включен) и запускает повторный разбор. Отключение отложенного повторного разбора имеет последствия для безопасности; подробности см. в xml.parsers.expat.xmlparser.SetReparseDeferralEnabled().

Обратите внимание, что flush() был добавлен в некоторые предыдущие выпуски CPython в качестве исправления безопасности. Если код выполняется в разных версиях Python, проверьте доступность flush() с помощью hasattr().

Добавлено в версии 3.13.

XMLParser.feed() вызывает метод start(tag, attrs_dict) объекта target для каждого открывающего тега, его метод end(tag) — для каждого закрывающего тега, а данные обрабатываются методом data(data). Другие поддерживаемые методы обратного вызова описаны в классе TreeBuilder. XMLParser.close() вызывает метод close() объекта target. XMLParser можно использовать не только для построения древовидной структуры. В следующем примере подсчитывается максимальная глубина файла XML:

>>> from xml.etree.ElementTree import XMLParser
>>> class MaxDepth:                     # The target object of the parser
...     maxDepth = 0
...     depth = 0
...     def start(self, tag, attrib):   # Called for each opening tag.
...         self.depth += 1
...         if self.depth > self.maxDepth:
...             self.maxDepth = self.depth
...     def end(self, tag):             # Called for each closing tag.
...         self.depth -= 1
...     def data(self, data):
...         pass            # We do not need to do anything with data.
...     def close(self):    # Called when all data has been parsed.
...         return self.maxDepth
...
>>> target = MaxDepth()
>>> parser = XMLParser(target=target)
>>> exampleXml = """
... <a>
...   <b>
...   </b>
...   <b>
...     <c>
...       <d>
...       </d>
...     </c>
...   </b>
... </a>"""
>>> parser.feed(exampleXml)
>>> parser.close()
4

Объекты XMLPullParser

class xml.etree.ElementTree.XMLPullParser(events=None)

Потоковый парсер, подходящий для неблокирующих приложений. Его API для ввода похож на API класса XMLParser, однако вместо передачи вызовов целевому объекту обратного вызова XMLPullParser собирает внутренний список событий разбора, из которого пользователь может считывать данные. events — последовательность событий, которые нужно сообщать. Поддерживаются события "start", "end", "comment", "pi", "start-ns" и "end-ns" (события «ns» используются для получения подробной информации о пространствах имен). Если events не указано, сообщаются только события "end".

feed(data)

Передает указанные байтовые данные парсеру.

flush()

Запускает разбор ранее переданных, но еще не обработанных данных, что позволяет получать обратную связь быстрее, особенно при использовании Expat >=2.6.0. Реализация flush() временно отключает отложенный повторный разбор в Expat (если он включен) и запускает повторный разбор. Отключение отложенного повторного разбора имеет последствия для безопасности; подробности см. в xml.parsers.expat.xmlparser.SetReparseDeferralEnabled().

Обратите внимание, что flush() был добавлен в некоторые предыдущие выпуски CPython в качестве исправления безопасности. Если код выполняется в разных версиях Python, проверьте доступность flush() с помощью hasattr().

Добавлено в версии 3.13.

close()

Сообщает парсеру, что поток данных завершен. В отличие от XMLParser.close(), этот метод всегда возвращает None. События, которые еще не были получены к моменту закрытия парсера, по-прежнему можно прочитать с помощью read_events().

read_events()

Возвращает итератор по событиям, обнаруженным в данных, переданных парсеру. Итератор возвращает пары (event, elem), где event — строка, обозначающая тип события (например, "end"), а elem — обнаруженный объект Element или другое значение контекста, как описано ниже.

  • start, end: текущий элемент.
  • comment, pi: текущий комментарий / инструкция обработки
  • start-ns: кортеж (prefix, uri), содержащий объявленное сопоставление пространств имен.
  • end-ns: None (в будущей версии это может измениться)

События, предоставленные при предыдущем вызове read_events(), повторно возвращаться не будут. События удаляются из внутренней очереди только при их получении из итератора, поэтому параллельная итерация нескольких читателей по итераторам, полученным из read_events(), приведет к непредсказуемым результатам.

Примечание

XMLPullParser гарантирует только то, что при возникновении события «start» он встретил символ «>» открывающего тега. Поэтому атрибуты уже определены, но содержимое атрибутов text и tail на этом этапе не определено. То же относится к дочерним элементам: они могут присутствовать, а могут и отсутствовать.

Если вам нужен полностью заполненный элемент, используйте события «end».

Добавлено в версии 3.4.

Изменено в версии 3.8: Добавлены события comment и pi.

Исключения

class xml.etree.ElementTree.ParseError

Ошибка разбора XML, возникающая при сбое разбора в различных методах этого модуля. Строковое представление экземпляра этого исключения содержит понятное пользователю сообщение об ошибке. Кроме того, доступны следующие атрибуты:

code

Числовой код ошибки парсера expat. Список кодов ошибок и их значения см. в документации xml.parsers.expat.

position

Кортеж из номеров строки и столбца, указывающий место возникновения ошибки.

Сноски

[1] (1,2,3,4)

Строка кодировки, включаемая в вывод 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–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/xml.etree.elementtree.html

Spec-Zone.ru

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