xml.etree.ElementTree — ElementTree XML API

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


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

Изменено в версии 3.3: Модуль будет использовать быструю реализацию, когда это возможно. Модуль xml.etree.cElementTree устарел.

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

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

Учебник

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

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

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

Синтаксический анализ 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.

Извлечение 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

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

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

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

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, где prefix заменяется полным URI. Кроме того, при наличии пространство имен по умолчанию этот полный URI добавляется ко всем тегам без префиксов.

Вот пример XML, который включает в себя два пространства имен, одно с префиксом «вымышленный», а другое служит в качестве пространства имен по умолчанию:

<?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

Дополнительные ресурсы

Руководства и ссылки на другие документы см. в разделе http://effbot.org/zone/element-index.htm.

Поддержка XPath

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

Пример

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

import xml.etree.ElementTree as ET

root = ET.fromstring(countrydata)

# Элементы верхнего уровня
root.findall(".")

# Все "neighbor" дети "country" детей элементов высшего уровня
root.findall("./country/neighbor")

# Узлы с name='Singapore', имеющие дочерний 'year'
root.findall(".//year/..[@name='Singapore']")

# 'year' узлы, которые являются дочерними узлами узлов с name='Singapore'
root.findall(".//*[@name='Singapore']/year")

# Все "соседние" узлы, которые являются вторым нижестоящим элементом их родителя
root.findall(".//neighbor[2]")

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

# Все дубликатные теги "title" в документе
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'] Выбирает все элементы, для которых данный атрибут имеет заданный значение. В значение не могут содержаться кавычки.
[tag] Выбор всех элементов, имеющих дочерний элемент с именем tag. Поддерживаются только непосредственные дети.
[.='text']

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

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

[tag='text'] Выбирает все элементы, имеющие дочерний элемент с именем tag полное текстовое содержимое которых, включая потомков, равно заданному text.
[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-комментарий стандартным сериализатором. Строка комментария может быть либо байтестрингом, либо строка Юникода. 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.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).

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

Примечание

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

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

Не рекомендуется, начиная с версии 3.4: Аргумент parser.

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

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 пропускает инструкции по обработке во входных данных вместо создания для них объектов комментариев. В 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: s. text является строка, содержащим XML-данные. parser является необязательным парсером сущность. Если не указано, то стандартная XMLParser парсер является используемый. Возвращает кортеж, содержащий Element сущность и словарь.

XIinclude поддержка

Модуль обеспечивает ограниченную поддержку 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)

Модуль ElireInclude заменяет {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", это сущность ElireTree. Если режим синтаксического анализа - «text», это строка Юникода. При сбое загрузчика это может возвращает None или вызвать исключение.

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

Функция расширяет директивы XIinclude. elem является корневым элементом. loader является дополнительным загрузчиком ресурсов. Если этот параметр опущен, по умолчанию используется значение default_loader(). Если этот параметр задан, он должен быть вызываемым, который реализует тот же интерфейс, что и default_loader(). Возвращает расширенный ресурс. Если режим синтаксического анализа "xml", это сущность ElireTree. Если режим синтаксического анализа - «text», это строка Юникода. При сбое загрузчика это может возвращает None или вызвать исключение.

Объекты элемента

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

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

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

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

clear()

Сброс элемента. Эта функция удаляет все вложенные элементы, очищает все атрибуты и устанавливает атрибуты текста и конца 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 является необязательным сопоставлением префикса пространства имен с полным именем. Передайте '' в качестве префикса, чтобы переместить все нефиксированные имена тегов в выражении в данное пространство имен.

getchildren()

Deprecated since version 3.2, will be removed in version 3.9: Использовать list(elem) или итерацию.

getiterator(tag=None)

Deprecated since version 3.2, will be removed in version 3.9: Вместо этого используйте метод Element.iter().

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. Такое поведение изменится в будущих версиях. Вместо этого используйте определенные len(elem) или elem is None тест.:

element = root.find('foo')

if not element:  # осторожно!
    print("element not found, or element has no subelements")

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

До 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:
            # скорректировать порядок атрибут, например, путем сортировки
            attribs = sorted(attrib.items())
            attrib.clear()
            attrib.update(attribs)

Объекты ElityTree

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

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

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

_setroot(element)

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

find(match, namespaces=None)

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

findall(match, namespaces=None)

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

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

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

getiterator(tag=None)

Deprecated since version 3.2, will be removed in version 3.9: Вместо этого используйте метод ElementTree.iter().

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 или юникод (по умолчанию None). default_namespace задает пространство имен XML по умолчанию (для «xmlns»). method имеет значение "xml", "html" или "text" (по умолчанию - "xml"). Параметр ключевой-only short_empty_elements управляет форматированием элементов, не содержащих содержимого. Если True (по умолчанию), они выдаются как один самозакрытый тег, в противном случае они выдаются как пара начальных/конечных тегов.

Выходной сигнал является либо строка (str), либо двоичным (bytes). Это контролируется аргументом encoding. Если encoding равно "Юникод", то выходной сигнал представляет собой строка; в противном случае, он двоичный. Обратите внимание, что это может конфликтовать с типом 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")     # Находит первое вхождение тега p в body
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a"))   # Возвращает список всех ссылок
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in 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} локальная, или, если задан аргумент тега, 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, комментарии/pis будут вставлены в дерево, если они появляются внутри корневого элемента (но не вне его).

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 - идентификатор public. 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 - это кодированный данные.

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:                     # Целевой объект парсера
...     maxDepth = 0
...     depth = 0
...     def start(self, tag, attrib):   # Вызывается для каждого открывающего тега.
...         self.depth += 1
...         if self.depth > self.maxDepth:
...             self.maxDepth = self.depth
...     def end(self, tag):             # Вызывается для каждого закрывающего тега.
...         self.depth -= 1
...     def data(self, data):
...         pass            # Нам не нужно ничего делать с данными.
...     def close(self):    # Вызывается после анализа всех данных.
...         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)

Передача данных в байтах в парсер.

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», поэтому атрибуты определены, но содержимое текста и хвостового атрибуты в этот момент не определены. То же самое относится и к дочерним элементам; они могут присутствовать или отсутствовать.

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

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

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

Исключения

class xml.etree.ElementTree.ParseError

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

code

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

position

Кортеж line, column номера, указывающие, где произошла ошибка.

Сноски

[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.