Spec-Zone.ru › Python 3.13

xml.etree.ElementTree — API XML ElementTree

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

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

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

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

Предупреждение

Модуль xml.etree.ElementTree не защищен от данных, созданных злоумышленником. Если вам нужно разобрать недоверенные или неаутентифицированные данные, см. Уязвимости XML.

Учебник

Это краткий учебник по использованию xml.etree.ElementTree (ET коротко). Цель – продемонстрировать некоторые строительные блоки и основные концепции модуля.

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

XML – это по своей природе иерархический формат данных, и самый естественный способ его представления – дерево. ET имеет два класса для этой цели – ElementTree представляет весь документ XML как дерево, а Element представляет собой отдельный узел в этом дереве. Взаимодействие с целым документом (чтение и запись в/из файлов) обычно выполняется на уровне ElementTree. Взаимодействие с отдельным элементом XML и его дочерними элементами выполняется на уровне Element.

Парсинг XML

Мы будем использовать вымышленный country_data.xml документ 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 и по частям подавать данные в него, но это API "push", который вызывает методы целевого обратного вызова, что слишком низкоуровнево и неудобно для большинства нужд. Иногда пользователь на самом деле хочет иметь возможность по частям анализировать 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 модуля. Мы будем использовать countrydata XML-документ из раздела Разбор 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{номер}”

    (по умолчанию: 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 может быть элементом или деревом элементов. 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)

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

Имя элемента, имена атрибутов и значения атрибутов могут быть либо строками байтов, либо строками Юникода. 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" для генерации строки Юникода (в противном случае генерируется строка байтов). 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" для генерации строки Юникода (в противном случае генерируется строка байтов). 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-раздел из константы строки и также возвращает словарь, в котором элементы id отображаются на элементы. 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.

Объекты элементов

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

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

Имя элемента, имена атрибутов и значения атрибутов могут быть строками байтов или строками 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 Information Set явно исключает порядок атрибутов из передачи информации. Код должен быть готов к работе с любым порядком на входе. В тех случаях, когда требуется детерминированный вывод 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 — корневой элемент. Дерево инициализируется содержимым 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 — строка. Это должна быть строка байтов или строка Юникода.

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)

Обрабатывает объявление типа документа. name — имя типа документа. 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(), а события парсинга переводятся в API push — путём вызова обратных вызовов объекта 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 как исправление безопасности. Проверьте доступность flush() с помощью hasattr(), если вы используете код, который работает на различных версиях Python.

Добавлена в версии 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 как исправление безопасности. Проверьте доступность flush() с помощью hasattr(), если используется в коде, работающем на разных версиях Python.

Добавлен в версии 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–2024 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