Документация Python неофициальный перевод

xml.etree.elementtree.md

1016 строк · 93.5 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.11/library/xml.etree.elementtree.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`xml.etree.ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) – API ElementTree для XML89**Исходный код:** [Lib/xml/etree/ElementTree.py](https://python-all.ru/src/3.11/Lib/xml/etree/ElementTree.py)1011---1213Модуль [`xml.etree.ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) реализует простой и эффективный API для разбора и создания XML-данных.1415Изменено в версии 3.3: Этот модуль использует быструю реализацию, если она доступна.1617Устарело с версии 3.3: Модуль `xml.etree.cElementTree` устарел.1819> **Предупреждение**20>21> Модуль [`xml.etree.ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) не защищён от вредоносных данных. Если нужно разобрать непроверенные или неаутентифицированные данные, см. [уязвимости XML](https://python-all.ru/3.11/library/xml.html#xml-vulnerabilities).2223## Учебное руководство2425Это краткое руководство по использованию [`xml.etree.ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#module-xml.etree.ElementTree) (`ET` в краткой форме). Цель – продемонстрировать некоторые основные компоненты и базовые концепции модуля.2627### XML-дерево и элементы2829XML – это изначально иерархический формат данных, и наиболее естественный способ его представления – дерево. `ET` содержит два класса для этой цели: [`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree) представляет весь XML-документ как дерево, а [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element) представляет отдельный узел в этом дереве. Взаимодействие со всем документом (чтение и запись в файлы/из файлов) обычно выполняется на уровне [`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree). Взаимодействие с отдельным элементом XML и его дочерними элементами выполняется на уровне [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).3031### Разбор XML3233В качестве примера для этого раздела мы будем использовать вымышленный XML-документ `country_data.xml`:3435```xml36<?xml version="1.0"?>37<data>38    <country name="Liechtenstein">39        <rank>1</rank>40        <year>2008</year>41        <gdppc>141100</gdppc>42        <neighbor name="Austria" direction="E"/>43        <neighbor name="Switzerland" direction="W"/>44    </country>45    <country name="Singapore">46        <rank>4</rank>47        <year>2011</year>48        <gdppc>59900</gdppc>49        <neighbor name="Malaysia" direction="N"/>50    </country>51    <country name="Panama">52        <rank>68</rank>53        <year>2011</year>54        <gdppc>13600</gdppc>55        <neighbor name="Costa Rica" direction="W"/>56        <neighbor name="Colombia" direction="E"/>57    </country>58</data>59```6061Данные можно импортировать, прочитав файл:6263```python64import xml.etree.ElementTree as ET65tree = ET.parse('country_data.xml')66root = tree.getroot()67```6869Или непосредственно из строки:7071```python72root = ET.fromstring(country_data_as_string)73```7475[`fromstring()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.fromstring) разбирает XML из строки непосредственно в [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element), который является корневым элементом разобранного дерева. Другие функции разбора могут создавать [`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree). Для уточнения обратитесь к документации.7677Как [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element), `root` имеет тег и словарь атрибутов:7879```python80>>> root.tag81'data'82>>> root.attrib83{}84```8586У него также есть дочерние узлы, которые можно перебирать:8788```python89>>> for child in root:90...     print(child.tag, child.attrib)91...92country {'name': 'Liechtenstein'}93country {'name': 'Singapore'}94country {'name': 'Panama'}95```9697Дочерние узлы вложены, и к конкретным дочерним узлам можно обратиться по индексу:9899```python100>>> root[0][1].text101'2008'102```103104> **Примечание**105>106> Не все элементы XML-входных данных станут элементами разобранного дерева. В настоящее время этот модуль пропускает любые XML-комментарии, инструкции по обработке и объявления типа документа во входных данных. Тем не менее, деревья, построенные с помощью API этого модуля, а не путём разбора XML-текста, могут содержать комментарии и инструкции по обработке; они будут включены при генерации XML-вывода. Доступ к объявлению типа документа можно получить, передав пользовательский экземпляр [`TreeBuilder`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder) конструктору [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser).107108### Pull API для неблокирующего разбора109110Большинство функций разбора, предоставляемых этим модулем, требуют, чтобы весь документ был прочитан сразу перед возвратом какого-либо результата. Можно использовать [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) и передавать в него данные постепенно, но это push API, который вызывает методы на целевом колбэке, что является слишком низкоуровневым и неудобным для большинства задач. Иногда пользователю действительно нужно иметь возможность разбирать XML постепенно, без блокирующих операций, пользуясь удобством полностью построенных объектов [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).111112Самый мощный инструмент для этого – [`XMLPullParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser). Он не требует блокирующего чтения для получения XML-данных, а вместо этого получает данные постепенно с помощью вызовов [`XMLPullParser.feed()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.feed). Чтобы получить разобранные XML-элементы, вызовите [`XMLPullParser.read_events()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.read_events). Вот пример:113114```python115>>> parser = ET.XMLPullParser(['start', 'end'])116>>> parser.feed('<mytag>sometext')117>>> list(parser.read_events())118[('start', <Element 'mytag' at 0x7fa66db2be58>)]119>>> parser.feed(' more text</mytag>')120>>> for event, elem in parser.read_events():121...     print(event)122...     print(elem.tag, 'text=', elem.text)123...124end125mytag text= sometext more text126```127128Очевидный вариант использования – приложения, работающие в неблокирующем режиме, где XML-данные поступают из сокета или читаются постепенно с какого-либо устройства хранения. В таких случаях блокирующие чтения неприемлемы.129130Из-за своей гибкости [`XMLPullParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser) может быть неудобен для более простых задач. Если вы не против того, чтобы ваше приложение блокировалось при чтении XML-данных, но всё же хотите иметь возможность инкрементального разбора, обратите внимание на [`iterparse()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.iterparse). Он может быть полезен при чтении большого XML-документа, который вы не хотите полностью хранить в памяти.131132Там, где требуется *немедленная* обратная связь через события, вызов метода [`XMLPullParser.flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.flush) может помочь уменьшить задержку; пожалуйста, обязательно изучите соответствующие замечания по безопасности.133134### Поиск интересующих элементов135136[`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element) имеет несколько полезных методов, которые помогают рекурсивно обходить всё поддерево под ним (его дочерние элементы, их дочерние элементы и так далее). Например, [`Element.iter()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.iter):137138```python139>>> for neighbor in root.iter('neighbor'):140...     print(neighbor.attrib)141...142{'name': 'Austria', 'direction': 'E'}143{'name': 'Switzerland', 'direction': 'W'}144{'name': 'Malaysia', 'direction': 'N'}145{'name': 'Costa Rica', 'direction': 'W'}146{'name': 'Colombia', 'direction': 'E'}147```148149[`Element.findall()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findall) находит только элементы с тегом, которые являются прямыми дочерними элементами текущего элемента. [`Element.find()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.find) находит *первый* дочерний элемент с указанным тегом, а [`Element.text`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.text) обращается к текстовому содержимому элемента. [`Element.get()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.get) обращается к атрибутам элемента:150151```python152>>> for country in root.findall('country'):153...     rank = country.find('rank').text154...     name = country.get('name')155...     print(name, rank)156...157Liechtenstein 1158Singapore 4159Panama 68160```161162Более сложное задание критериев поиска элементов возможно с помощью [XPath](https://python-all.ru/3.11/library/xml.etree.elementtree.html#elementtree-xpath).163164### Изменение XML-файла165166[`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree) предоставляет простой способ создания XML-документов и записи их в файлы. Метод [`ElementTree.write()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree.write) служит этой цели.167168После создания объект [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element) можно изменять, напрямую меняя его поля (например, [`Element.text`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.text)), добавляя и изменяя атрибуты (метод [`Element.set()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.set)), а также добавляя новые дочерние элементы (например, с помощью [`Element.append()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.append)).169170Допустим, мы хотим увеличить ранг каждой страны на единицу и добавить атрибут `updated` к элементу ранга:171172```python173>>> for rank in root.iter('rank'):174...     new_rank = int(rank.text) + 1175...     rank.text = str(new_rank)176...     rank.set('updated', 'yes')177...178>>> tree.write('output.xml')179```180181Теперь наш XML выглядит так:182183```xml184<?xml version="1.0"?>185<data>186    <country name="Liechtenstein">187        <rank updated="yes">2</rank>188        <year>2008</year>189        <gdppc>141100</gdppc>190        <neighbor name="Austria" direction="E"/>191        <neighbor name="Switzerland" direction="W"/>192    </country>193    <country name="Singapore">194        <rank updated="yes">5</rank>195        <year>2011</year>196        <gdppc>59900</gdppc>197        <neighbor name="Malaysia" direction="N"/>198    </country>199    <country name="Panama">200        <rank updated="yes">69</rank>201        <year>2011</year>202        <gdppc>13600</gdppc>203        <neighbor name="Costa Rica" direction="W"/>204        <neighbor name="Colombia" direction="E"/>205    </country>206</data>207```208209Элементы можно удалять с помощью [`Element.remove()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.remove). Допустим, мы хотим удалить все страны с рангом выше 50:210211```python212>>> for country in root.findall('country'):213...     # использование root.findall() для предотвращения удаления во время обхода214...     rank = int(country.find('rank').text)215...     if rank > 50:216...         root.remove(country)217...218>>> tree.write('output.xml')219```220221Обратите внимание: одновременное изменение коллекции во время итерации может привести к проблемам, так же как при итерации и изменении списков или словарей Python. Поэтому в примере сначала собираются все подходящие элементы с помощью `root.findall()`, и только потом выполняется итерация по списку совпадений.222223Теперь наш XML выглядит так:224225```xml226<?xml version="1.0"?>227<data>228    <country name="Liechtenstein">229        <rank updated="yes">2</rank>230        <year>2008</year>231        <gdppc>141100</gdppc>232        <neighbor name="Austria" direction="E"/>233        <neighbor name="Switzerland" direction="W"/>234    </country>235    <country name="Singapore">236        <rank updated="yes">5</rank>237        <year>2011</year>238        <gdppc>59900</gdppc>239        <neighbor name="Malaysia" direction="N"/>240    </country>241</data>242```243244### Создание XML-документов245246Функция [`SubElement()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.SubElement) также предоставляет удобный способ создания новых дочерних элементов для заданного элемента:247248```python249>>> a = ET.Element('a')250>>> b = ET.SubElement(a, 'b')251>>> c = ET.SubElement(a, 'c')252>>> d = ET.SubElement(c, 'd')253>>> ET.dump(a)254<a><b /><c><d /></c></a>255```256257### Разбор XML с пространствами имён258259Если во входном XML есть [пространства имён](https://python-all.ru/3.11/library/xml.etree.elementtree.html), теги и атрибуты с префиксами вида `prefix:sometag` раскрываются до `{uri}sometag`, где *префикс* заменяется полным *URI*. Кроме того, если есть [пространство имён по умолчанию](https://python-all.ru/3.11/library/xml.etree.elementtree.html), то этот полный URI добавляется в начало всех тегов без префикса.260261Вот пример XML, в котором используются два пространства имён: одно с префиксом «fictional», а другое выступает в качестве пространства имён по умолчанию:262263```xml264<?xml version="1.0"?>265<actors xmlns:fictional="http://characters.example.com"266        xmlns="http://people.example.com">267    <actor>268        <name>John Cleese</name>269        <fictional:character>Lancelot</fictional:character>270        <fictional:character>Archie Leach</fictional:character>271    </actor>272    <actor>273        <name>Eric Idle</name>274        <fictional:character>Sir Robin</fictional:character>275        <fictional:character>Gunther</fictional:character>276        <fictional:character>Commander Clement</fictional:character>277    </actor>278</actors>279```280281Один из способов поиска и изучения этого XML-примера – вручную добавить URI к каждому тегу или атрибуту в XPath-выражении [`find()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.find) или [`findall()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findall):282283```python284root = fromstring(xml_text)285for actor in root.findall('{http://people.example.com}actor'):286    name = actor.find('{http://people.example.com}name')287    print(name.text)288    for char in actor.findall('{http://characters.example.com}character'):289        print(' |-->', char.text)290```291292Более удобный способ поиска в XML с пространствами имён – создать словарь с собственными префиксами и использовать их в функциях поиска:293294```python295ns = {'real_person': 'http://people.example.com',296      'role': 'http://characters.example.com'}297298for actor in root.findall('real_person:actor', ns):299    name = actor.find('real_person:name', ns)300    print(name.text)301    for char in actor.findall('role:character', ns):302        print(' |-->', char.text)303```304305Оба подхода выводят одно и то же:306307```python308John Cleese309 |--> Lancelot310 |--> Archie Leach311Eric Idle312 |--> Sir Robin313 |--> Gunther314 |--> Commander Clement315```316317## Поддержка XPath318319Этот модуль предоставляет ограниченную поддержку [XPath-выражений](https://python-all.ru/3.11/library/xml.etree.elementtree.html) для поиска элементов в дереве. Цель – поддержать небольшое подмножество сокращённого синтаксиса; полноценный движок XPath выходит за рамки модуля.320321### Пример322323Вот пример, демонстрирующий некоторые возможности XPath этого модуля. Будем использовать XML-документ `countrydata` из раздела [Разбор XML](https://python-all.ru/3.11/library/xml.etree.elementtree.html#elementtree-parsing-xml):324325```python326import xml.etree.ElementTree as ET327328root = ET.fromstring(countrydata)329330# Элементы верхнего уровня331root.findall(".")332333# Все элементы 'neighbor', являющиеся внуками дочерних элементов 'country' верхнего уровня334# элементы335root.findall("./country/neighbor")336337# Узлы с name='Singapore', имеющие дочерний элемент 'year'338root.findall(".//year/..[@name='Singapore']")339340# Элементы 'year', являющиеся дочерними для узлов с name='Singapore'341root.findall(".//*[@name='Singapore']/year")342343# Все элементы 'neighbor', являющиеся вторым дочерним элементом своего родителя344root.findall(".//neighbor[2]")345```346347Для XML с пространствами имён используйте обычную нотацию с `{namespace}tag`:348349```python350# Все теги dublin-core "title" в документе351root.findall(".//{http://purl.org/dc/elements/1.1/}title")352```353354### Поддерживаемый синтаксис XPath355356| Синтаксис | Значение |357| --- | --- |358| `tag` | Выбирает все дочерние элементы с заданным тегом. Например, `spam` выбирает все дочерние элементы с именем `spam`, а `spam/egg` выбирает все внучатые элементы с именем `egg` среди всех дочерних с именем `spam`. `{namespace}*` выбирает все теги в заданном пространстве имён, `{*}spam` выбирает теги с именем `spam` в любом (или ни в каком) пространстве имён, а `{}*` выбирает только теги, не принадлежащие ни одному пространству имён. Изменено в версии 3.8: Добавлена поддержка подстановочных символов в виде звёздочки. |359| `*` | Выбирает все дочерние элементы, включая комментарии и инструкции обработки. Например, `*/egg` выбирает все внучатые элементы с именем `egg`. |360| `.` | Выбирает текущий узел. Это особенно полезно в начале пути, чтобы указать, что это относительный путь. |361| `//` | Выбирает все вложенные элементы на всех уровнях ниже текущего элемента. Например, `.//egg` выбирает все элементы `egg` во всём дереве. |362| `..` | Выбирает родительский элемент. Возвращает `None`, если путь пытается достичь предков начального элемента (элемента, для которого был вызван `find`). |363| `[@attrib]` | Выбирает все элементы, у которых есть указанный атрибут. |364| `[@attrib='value']` | Выбирает все элементы, у которых указанный атрибут имеет заданное значение. Значение не может содержать кавычки. |365| `[@attrib!='value']` | Выбирает все элементы, у которых указанный атрибут не равен заданному значению. Значение не может содержать кавычки. Новое в версии 3.10. |366| `[tag]` | Выбирает все элементы, у которых есть дочерний элемент с именем `tag`. Поддерживаются только непосредственные дочерние элементы. |367| `[.='text']` | Выбирает все элементы, полное текстовое содержимое которых, включая потомков, равно заданному `text`. Добавлено в версии 3.7. |368| `[.!='text']` | Выбирает все элементы, полное текстовое содержимое которых, включая потомков, не равно заданному `text`. Новое в версии 3.10. |369| `[tag='text']` | Выбирает все элементы, у которых есть дочерний элемент с именем `tag`, чьё полное текстовое содержимое, включая потомков, равно заданному `text`. |370| `[tag!='text']` | Выбирает все элементы, у которых есть дочерний элемент с именем `tag`, чьё полное текстовое содержимое, включая потомков, не равно заданному `text`. Новое в версии 3.10. |371| `[position]` | Выбирает все элементы, расположенные на указанной позиции. Позиция может быть целым числом (1 – первая позиция), выражением `last()` (для последней позиции) или позицией относительно последней позиции (например, `last()-1`). |372373Предикаты (выражения в квадратных скобках) должны предваряться именем тега, звёздочкой или другим предикатом. Предикаты `position` должны предваряться именем тега.374375## Ссылка376377### Функции378379#### `xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)`380381Функция преобразования [C14N 2.0](https://python-all.ru/3.11/library/xml.etree.elementtree.html).382383Канонизация – это способ нормализации XML-вывода, позволяющий побайтовое сравнение и цифровые подписи. Она сокращает свободу XML-сериализаторов и вместо этого генерирует более ограниченное XML-представление. Основные ограничения касаются размещения объявлений пространств имен, порядка атрибутов и игнорируемых пробелов.384385Эта функция принимает на вход строку XML-данных (*xml\_data*) или путь к файлу или файлоподобный объект (*from\_file*), преобразует их в каноническую форму и записывает результат с помощью файлоподобного объекта *out*, если он указан, или возвращает его в виде текстовой строки, если не указан. Выходной файл получает текст, а не байты. Поэтому он должен быть открыт в текстовом режиме с кодировкой `utf-8`.386387Типичное использование:388389```python390xml_data = "<root>...</root>"391print(canonicalize(xml_data))392393with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:394    canonicalize(xml_data, out=out_file)395396with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file:397    canonicalize(from_file="inputfile.xml", out=out_file)398```399400Параметры конфигурации *options* следующие:401402- *with\_comments*: установите true, чтобы включить комментарии (по умолчанию: false)403- ***strip\_text*: установите true, чтобы удалять пробелы до и после текстового содержимого**404405  (по умолчанию: false)406- ***rewrite\_prefixes*: установите true, чтобы заменять префиксы пространств имён на “n{number}”**407408  (по умолчанию: false)409- ***qname\_aware\_tags*: набор имен тегов, учитывающих qname, в которых префиксы**410411  должны заменяться в текстовом содержимом (по умолчанию: пусто)412- ***qname\_aware\_attrs*: набор имен атрибутов, учитывающих qname, в которых префиксы**413414  должны заменяться в текстовом содержимом (по умолчанию: пусто)415- *exclude\_attrs*: набор имен атрибутов, которые не должны сериализоваться416- *exclude\_tags*: набор имен тегов, которые не должны сериализоваться417418В приведённом выше списке параметров под «набором» понимается любая коллекция или итерабельный объект из строк, порядок не важен.419420Новое в версии 3.8.421422#### `xml.etree.ElementTree.Comment(text=None)`423424Фабрика элементов Comment. Эта фабричная функция создаёт специальный элемент, который будет сериализован как XML-комментарий стандартным сериализатором. Строка комментария может быть как байтовой строкой, так и строкой Unicode. *text* – это строка, содержащая текст комментария. Возвращает экземпляр элемента, представляющий комментарий.425426Обратите внимание, что [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) пропускает комментарии во входных данных, не создавая для них объекты комментариев. [`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree) будет содержать узлы комментариев только в том случае, если они были вставлены в дерево с помощью одного из методов [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).427428#### `xml.etree.ElementTree.dump(elem)`429430Записывает дерево элементов или структуру элементов в sys.stdout. Эту функцию следует использовать только для отладки.431432Точный формат вывода зависит от реализации. В этой версии он записывается как обычный XML-файл.433434*elem* – это дерево элементов или отдельный элемент.435436Изменено в версии 3.8: Функция [`dump()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.dump) теперь сохраняет порядок атрибутов, заданный пользователем.437438#### `xml.etree.ElementTree.fromstring(text, parser=None)`439440Разбирает фрагмент XML из строковой константы. То же, что и [`XML()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XML). *text* – это строка, содержащая XML-данные. *parser* – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). Возвращает экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).441442#### `xml.etree.ElementTree.fromstringlist(sequence, parser=None)`443444Разбирает XML-документ из последовательности строковых фрагментов. *sequence* – это список или другая последовательность, содержащая фрагменты XML-данных. *parser* – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). Возвращает экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).445446Новое в версии 3.2.447448#### `xml.etree.ElementTree.indent(tree, space=' ', level=0)`449450Добавляет пробелы в поддерево для визуального отступа дерева. Это можно использовать для создания красиво отформатированного XML-вывода. *tree* может быть элементом Element или ElementTree. *space* – строка пробелов, которая будет вставлена для каждого уровня отступа, по умолчанию два пробела. Для отступа частичных поддеревьев внутри уже отформатированного дерева передайте начальный уровень отступа как *level*.451452Новое в версии 3.9.453454#### `xml.etree.ElementTree.iselement(element)`455456Проверяет, является ли объект допустимым элементом. *element* – это экземпляр элемента. Возвращает `True`, если это объект элемента.457458#### `xml.etree.ElementTree.iterparse(source, events=None, parser=None)`459460Разбирает XML-фрагмент в дерево элементов инкрементально и сообщает пользователю о происходящем. *source* – это имя файла или [файловый объект](https://python-all.ru/3.11/glossary.html#term-file-object), содержащий XML-данные. *events* – это последовательность событий, о которых нужно сообщать. Поддерживаемые события – строки `"start"`, `"end"`, `"comment"`, `"pi"`, `"start-ns"` и `"end-ns"` (события с «ns» используются для получения детальной информации о пространствах имён). Если *events* опущен, сообщается только о событиях `"end"`. *parser* – необязательный экземпляр парсера. Если не указан, используется стандартный парсер [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). *parser* должен быть подклассом [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) и может использовать только цель по умолчанию [`TreeBuilder`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder). Возвращает [итератор](https://python-all.ru/3.11/glossary.html#term-iterator), предоставляющий пары `(event, elem)`; он имеет атрибут `root`, который ссылается на корневой элемент результирующего XML-дерева после полного чтения *source*.461462Обратите внимание, что [`iterparse()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.iterparse) строит дерево инкрементально, но выполняет блокирующие чтения из *source* (или указанного файла). Поэтому он не подходит для приложений, где блокирующие чтения недопустимы. Для полностью неблокирующего разбора см. [`XMLPullParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser).463464> **Примечание**465>466> [`iterparse()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.iterparse) гарантирует только, что увидел символ «\>» начального тега, когда генерирует событие «start», поэтому атрибуты определены, но содержимое атрибутов text и tail на этот момент не определено. То же самое относится к дочерним элементам; они могут присутствовать или нет.467>468> Если нужен полностью заполненный элемент, используйте события "end".469470Устарело с версии 3.4: Аргумент *parser*.471472Изменено в версии 3.8: Были добавлены события `comment` и `pi`.473474#### `xml.etree.ElementTree.parse(source, parser=None)`475476Разбирает XML-раздел в дерево элементов. *source* – это имя файла или файловый объект, содержащий XML-данные. *parser* – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). Возвращает экземпляр [`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree).477478#### `xml.etree.ElementTree.ProcessingInstruction(target, text=None)`479480Фабрика PI-элементов. Эта фабричная функция создаёт специальный элемент, который будет сериализован как инструкция обработки XML. *target* – строка, содержащая цель PI. *text* – строка, содержащая содержимое PI, если задано. Возвращает экземпляр элемента, представляющий инструкцию обработки.481482Обратите внимание, что [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) пропускает инструкции обработки во входных данных вместо создания для них PI-объектов. [`ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree) будет содержать узлы инструкций обработки, только если они были вставлены в дерево с помощью одного из методов [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).483484#### `xml.etree.ElementTree.register_namespace(prefix, uri)`485486Регистрирует префикс пространства имён. Реестр является глобальным, и любое существующее сопоставление для данного префикса или URI пространства имён будет удалено. *prefix* – префикс пространства имён. *uri* – URI пространства имён. Теги и атрибуты в этом пространстве имён будут сериализованы с указанным префиксом, если это возможно.487488Новое в версии 3.2.489490#### `xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)`491492Фабрика подэлементов. Эта функция создаёт экземпляр элемента и добавляет его к существующему элементу.493494Имя элемента, имена атрибутов и значения атрибутов могут быть как байтовыми строками, так и строками Unicode. *parent* – родительский элемент. *tag* – имя подэлемента. *attrib* – необязательный словарь, содержащий атрибуты элемента. *extra* содержит дополнительные атрибуты, заданные как именованные аргументы. Возвращает экземпляр элемента.495496#### `xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)`497498Создаёт строковое представление XML-элемента, включая все подэлементы. *element* – это экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element). *encoding* [\[1\]](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id9) – выходная кодировка (по умолчанию US-ASCII). Используйте `encoding="unicode"` для создания строки Unicode (в противном случае создаётся байтовая строка). *method* – это либо `"xml"`, `"html"` или `"text"` (по умолчанию `"xml"`). *xml\_declaration*, *default\_namespace* и *short\_empty\_elements* имеют тот же смысл, что и в [`ElementTree.write()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree.write). Возвращает (опционально) закодированную строку, содержащую XML-данные.499500Изменено в версии 3.4: Добавлен параметр *short\_empty\_elements*.501502Изменено в версии 3.8: Добавлены параметры *xml\_declaration* и *default\_namespace*.503504Изменено в версии 3.8: Функция [`tostring()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostring) теперь сохраняет порядок атрибутов, заданный пользователем.505506#### `xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)`507508Создаёт строковое представление XML-элемента, включая все подэлементы. *element* – это экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element). *encoding* [\[1\]](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id9) – выходная кодировка (по умолчанию US-ASCII). Используйте `encoding="unicode"` для создания строки Unicode (в противном случае создаётся байтовая строка). *method* – это либо `"xml"`, `"html"` или `"text"` (по умолчанию `"xml"`). *xml\_declaration*, *default\_namespace* и *short\_empty\_elements* имеют тот же смысл, что и в [`ElementTree.write()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree.write). Возвращает список (опционально) закодированных строк, содержащих XML-данные. Не гарантируется никакой конкретный порядок, за исключением того, что `b"".join(tostringlist(element)) == tostring(element)`.509510Новое в версии 3.2.511512Изменено в версии 3.4: Добавлен параметр *short\_empty\_elements*.513514Изменено в версии 3.8: Добавлены параметры *xml\_declaration* и *default\_namespace*.515516Изменено в версии 3.8: Функция [`tostringlist()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.tostringlist) теперь сохраняет порядок атрибутов, заданный пользователем.517518#### `xml.etree.ElementTree.XML(text, parser=None)`519520Разбирает XML-раздел из строковой константы. Эту функцию можно использовать для встраивания «XML-литералов» в код Python. *text* – строка, содержащая XML-данные. *parser* – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). Возвращает экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).521522#### `xml.etree.ElementTree.XMLID(text, parser=None)`523524Разбирает XML-фрагмент из строковой константы и возвращает словарь, сопоставляющий идентификаторы элементов с элементами. *text* – строка, содержащая XML-данные. *parser* – необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). Возвращает кортеж, содержащий экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element) и словарь.525526## Поддержка XInclude527528Этот модуль предоставляет ограниченную поддержку [директив XInclude](https://python-all.ru/3.11/library/xml.etree.elementtree.html) через вспомогательный модуль [`xml.etree.ElementInclude`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#module-xml.etree.ElementInclude). Этот модуль можно использовать для вставки поддеревьев и текстовых строк в деревья элементов на основе информации в дереве.529530### Пример531532Вот пример, демонстрирующий использование модуля XInclude. Чтобы включить XML-документ в текущий документ, используйте элемент `{http://www.w3.org/2001/XInclude}include` и установите атрибут **parse** в `"xml"`, а атрибут **href** – для указания включаемого документа.533534```xml535<?xml version="1.0"?>536<document xmlns:xi="http://www.w3.org/2001/XInclude">537  <xi:include href="source.xml" parse="xml" />538</document>539```540541По умолчанию атрибут **href** рассматривается как имя файла. Можно использовать пользовательские загрузчики, чтобы переопределить это поведение. Также обратите внимание, что стандартный вспомогательный модуль не поддерживает синтаксис XPointer.542543Чтобы обработать этот файл, загрузите его как обычно и передайте корневой элемент модулю [`xml.etree.ElementTree`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#module-xml.etree.ElementTree):544545```python546from xml.etree import ElementTree, ElementInclude547548tree = ElementTree.parse("document.xml")549root = tree.getroot()550551ElementInclude.include(root)552```553554Модуль ElementInclude заменяет элемент `{http://www.w3.org/2001/XInclude}include` корневым элементом из документа **source.xml**. Результат может выглядеть примерно так:555556```xml557<document xmlns:xi="http://www.w3.org/2001/XInclude">558  <para>This is a paragraph.</para>559</document>560```561562Если атрибут **parse** опущен, по умолчанию используется «xml». Атрибут href является обязательным.563564Чтобы включить текстовый документ, используйте элемент `{http://www.w3.org/2001/XInclude}include` и установите атрибут **parse** в «text»:565566```xml567<?xml version="1.0"?>568<document xmlns:xi="http://www.w3.org/2001/XInclude">569  Copyright (c) <xi:include href="year.txt" parse="text" />.570</document>571```572573Результат может выглядеть примерно так:574575```xml576<document xmlns:xi="http://www.w3.org/2001/XInclude">577  Copyright (c) 2003.578</document>579```580581## Ссылка582583### Функции584585#### `xml.etree.ElementInclude.default_loader(href, parse, encoding=None)`586587Загрузчик по умолчанию. Этот загрузчик по умолчанию читает включённый ресурс с диска. *href* – это URL. *parse* – это режим разбора: либо «xml», либо «text». *encoding* – необязательная текстовая кодировка. Если не указана, используется `utf-8`. Возвращает развёрнутый ресурс. Если режим разбора – `"xml"`, это экземпляр ElementTree. Если режим разбора – «text», это строка Unicode. Если загрузчику не удаётся загрузить, он может вернуть None или возбудить исключение.588589#### `xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)`590591Эта функция разворачивает директивы XInclude. *elem* – корневой элемент. *loader* – необязательный загрузчик ресурсов. Если опущен, по умолчанию используется [`default_loader()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementInclude.default_loader). Если указан, это должен быть вызываемый объект, реализующий тот же интерфейс, что и [`default_loader()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementInclude.default_loader). *base\_url* – базовый URL исходного файла для разрешения относительных путей включённых файлов. *max\_depth* – максимальное количество рекурсивных включений. Ограничено для снижения риска взрыва вредоносного содержимого. Передайте отрицательное значение, чтобы отключить ограничение.592593Возвращает развёрнутый ресурс. Если режим разбора – `"xml"`, это экземпляр ElementTree. Если режим разбора – «text», это строка Unicode. Если загрузчику не удаётся загрузить, он может вернуть None или возбудить исключение.594595Изменено в версии 3.9: Добавлены параметры *base\_url* и *max\_depth*.596597### Объекты Element598599#### `class xml.etree.ElementTree.Element(tag, attrib={}, **extra)`600601Класс Element. Этот класс определяет интерфейс Element и предоставляет эталонную реализацию этого интерфейса.602603Имя элемента, имена атрибутов и значения атрибутов могут быть либо байтовыми строками, либо строками Unicode. *tag* – имя элемента. *attrib* – необязательный словарь, содержащий атрибуты элемента. *extra* содержит дополнительные атрибуты, заданные как именованные аргументы.604605#### `tag`606607Строка, определяющая, какие данные представляет этот элемент (иначе говоря, тип элемента).608609#### `text`610611#### `tail`612613Эти атрибуты можно использовать для хранения дополнительных данных, связанных с элементом. Их значениями обычно являются строки, но могут быть и любые объекты, специфичные для приложения. Если элемент создан из XML-файла, атрибут *text* содержит либо текст между начальным тегом элемента и его первым дочерним элементом или закрывающим тегом, либо `None`, а атрибут *tail* содержит либо текст между закрывающим тегом элемента и следующим тегом, либо `None`. Для XML-данных614615```xml616<a><b>1<c>2<d/>3</c></b>4</a>617```618619элемент *a* имеет `None` для обоих атрибутов *text* и *tail*, элемент *b* имеет *text* `"1"` и *tail* `"4"`, элемент *c* имеет *text* `"2"` и *tail* `None`, а элемент *d* имеет *text* `None` и *tail* `"3"`.620621Чтобы собрать внутренний текст элемента, см. [`itertext()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.itertext), например `"".join(element.itertext())`.622623Приложения могут хранить в этих атрибутах произвольные объекты.624625#### `attrib`626627Словарь, содержащий атрибуты элемента. Обратите внимание, что хотя значение *attrib* всегда является настоящим изменяемым словарём Python, реализация ElementTree может использовать другое внутреннее представление и создавать словарь только по запросу. Чтобы воспользоваться преимуществами таких реализаций, по возможности используйте приведённые ниже методы словаря.628629Следующие методы, подобные словарным, работают с атрибутами элемента.630631#### `clear()`632633Сбрасывает элемент. Эта функция удаляет все подэлементы, очищает все атрибуты и устанавливает атрибуты text и tail в `None`.634635#### `get(key, default=None)`636637Возвращает атрибут элемента с именем *key*.638639Возвращает значение атрибута или *default*, если атрибут не найден.640641#### `items()`642643Возвращает атрибуты элемента в виде последовательности пар (имя, значение). Атрибуты возвращаются в произвольном порядке.644645#### `keys()`646647Возвращает имена атрибутов элемента в виде списка. Имена возвращаются в произвольном порядке.648649#### `set(key, value)`650651Устанавливает атрибут *key* элемента в *value*.652653Следующие методы работают с дочерними элементами (подэлементами) текущего элемента.654655#### `append(subelement)`656657Добавляет элемент *subelement* в конец внутреннего списка подэлементов текущего элемента. Возбуждает [`TypeError`](https://python-all.ru/3.11/library/exceptions.html#TypeError), если *subelement* не является [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).658659#### `extend(subelements)`660661Добавляет *подэлементы* из последовательности с нулём или более элементов. Возбуждает [`TypeError`](https://python-all.ru/3.11/library/exceptions.html#TypeError), если подэлемент не является [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).662663Новое в версии 3.2.664665#### `find(match, namespaces=None)`666667Находит первый подэлемент, соответствующий *match*. *match* может быть именем тега или [path](https://python-all.ru/3.11/library/xml.etree.elementtree.html#elementtree-xpath). Возвращает экземпляр элемента или `None`. *namespaces* – необязательное отображение префикса пространства имён на полное имя. Передайте `''` в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в указанное пространство имён.668669#### `findall(match, namespaces=None)`670671Находит все подходящие подэлементы по имени тега или [path](https://python-all.ru/3.11/library/xml.etree.elementtree.html#elementtree-xpath). Возвращает список, содержащий все подходящие элементы в порядке документа. *namespaces* – необязательное отображение префикса пространства имён на полное имя. Передайте `''` в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в указанное пространство имён.672673#### `findtext(match, default=None, namespaces=None)`674675Находит текст для первого подэлемента, соответствующего *match*. *match* может быть именем тега или [path](https://python-all.ru/3.11/library/xml.etree.elementtree.html#elementtree-xpath). Возвращает текстовое содержимое первого подходящего элемента или *default*, если элемент не найден. Обратите внимание: если у подходящего элемента нет текстового содержимого, возвращается пустая строка. *namespaces* – необязательное отображение префикса пространства имён на полное имя. Передайте `''` в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в указанное пространство имён.676677#### `insert(index, subelement)`678679Вставляет *subelement* в указанную позицию в этом элементе. Возбуждает [`TypeError`](https://python-all.ru/3.11/library/exceptions.html#TypeError), если *subelement* не является [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).680681#### `iter(tag=None)`682683Создаёт древовидный [итератор](https://python-all.ru/3.11/glossary.html#term-iterator) с текущим элементом в качестве корня. Итератор перебирает этот элемент и все элементы ниже него в порядке документа (сначала в глубину). Если *tag* не равен `None` или `'*'`, из итератора возвращаются только элементы, тег которых равен *tag*. Если структура дерева изменяется во время итерации, результат не определён.684685Новое в версии 3.2.686687#### `iterfind(match, namespaces=None)`688689Находит все подходящие подэлементы по имени тега или [path](https://python-all.ru/3.11/library/xml.etree.elementtree.html#elementtree-xpath). Возвращает итерируемый объект, выдающий все подходящие элементы в порядке документа. *namespaces* – необязательное отображение префикса пространства имён на полное имя.690691Новое в версии 3.2.692693#### `itertext()`694695Создаёт текстовый итератор. Итератор перебирает этот элемент и все подэлементы в порядке документа и возвращает весь внутренний текст.696697Новое в версии 3.2.698699#### `makeelement(tag, attrib)`700701Создаёт новый объект элемента того же типа, что и этот элемент. Не вызывайте этот метод, используйте вместо него фабричную функцию [`SubElement()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.SubElement).702703#### `remove(subelement)`704705Удаляет *subelement* из элемента. В отличие от методов find\*, этот метод сравнивает элементы по идентичности экземпляра, а не по значению тега или содержимому.706707Объекты [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element) также поддерживают следующие методы последовательностей для работы с подэлементами: [`__delitem__()`](https://python-all.ru/3.11/reference/datamodel.html#object.__delitem__), [`__getitem__()`](https://python-all.ru/3.11/reference/datamodel.html#object.__getitem__), [`__setitem__()`](https://python-all.ru/3.11/reference/datamodel.html#object.__setitem__), [`__len__()`](https://python-all.ru/3.11/reference/datamodel.html#object.__len__).708709Предупреждение: элементы без подэлементов будут проверяться как `False`. Это поведение изменится в будущих версиях. Вместо этого используйте конкретную проверку `len(elem)` или `elem is None`.710711```python712element = root.find('foo')713714if not element:  # осторожно!715    print("element not found, or element has no subelements")716717if element is None:718    print("element not found")719```720721До Python 3.8 порядок сериализации XML-атрибутов элементов искусственно делался предсказуемым за счёт сортировки атрибутов по имени. Опираясь на теперь гарантированный порядок словарей, это произвольное переупорядочивание было удалено в Python 3.8, чтобы сохранять тот порядок, в котором атрибуты были исходно разобраны или созданы пользовательским кодом.722723В целом пользовательскому коду не следует полагаться на определённый порядок атрибутов, поскольку [набор XML-информации](https://python-all.ru/3.11/library/xml.etree.elementtree.html) явно исключает порядок атрибутов из передачи информации. Код должен быть готов обрабатывать любой порядок на входе. В случаях, когда требуется детерминированный вывод XML, например для криптографической подписи или тестовых наборов данных, доступна каноническая сериализация с помощью функции [`canonicalize()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.canonicalize).724725В случаях, когда канонический вывод неприменим, но определённый порядок атрибутов всё же желателен, коду следует стремиться создавать атрибуты непосредственно в нужном порядке, чтобы избежать несоответствий для читающих код. Если это трудно реализовать, можно применить следующий приём перед сериализацией, чтобы задать порядок независимо от создания элемента:726727```python728def reorder_attributes(root):729    for el in root.iter():730        attrib = el.attrib731        if len(attrib) > 1:732            # измените порядок атрибутов, например, сортировкой733            attribs = sorted(attrib.items())734            attrib.clear()735            attrib.update(attribs)736```737738### Объекты ElementTree739740#### `class xml.etree.ElementTree.ElementTree(element=None, file=None)`741742Класс-обёртка ElementTree. Этот класс представляет целую иерархию элементов и добавляет дополнительную поддержку сериализации в стандартный XML и из него.743744*element* – корневой элемент. Дерево инициализируется содержимым XML-*файла*, если он указан.745746#### `_setroot(element)`747748Заменяет корневой элемент этого дерева. При этом текущее содержимое дерева отбрасывается и заменяется указанным элементом. Используйте с осторожностью. *element* – экземпляр элемента.749750#### `find(match, namespaces=None)`751752То же, что и [`Element.find()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.find), начиная с корня дерева.753754#### `findall(match, namespaces=None)`755756То же, что и [`Element.findall()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findall), начиная с корня дерева.757758#### `findtext(match, default=None, namespaces=None)`759760То же, что и [`Element.findtext()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.findtext), начиная с корня дерева.761762#### `getroot()`763764Возвращает корневой элемент этого дерева.765766#### `iter(tag=None)`767768Создаёт и возвращает итератор дерева для корневого элемента. Итератор обходит все элементы этого дерева в порядке следования разделов. *tag* – это тег, который нужно искать (по умолчанию возвращаются все элементы).769770#### `iterfind(match, namespaces=None)`771772То же, что и [`Element.iterfind()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element.iterfind), начиная с корня дерева.773774Новое в версии 3.2.775776#### `parse(source, parser=None)`777778Загружает внешний XML-раздел в это дерево элементов. *source* – это имя файла или [файловый объект](https://python-all.ru/3.11/glossary.html#term-file-object). *parser* – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser). Возвращает корневой элемент раздела.779780#### `write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml', *, short_empty_elements=True)`781782Записывает дерево элементов в файл в формате XML. *file* – это имя файла или [файловый объект](https://python-all.ru/3.11/glossary.html#term-file-object), открытый для записи. *encoding* [\[1\]](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id9) – выходная кодировка (по умолчанию 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` (по умолчанию), они выводятся как один самозакрывающийся тег, иначе – как пара открывающего и закрывающего тегов.783784Результат – либо строка ([`str`](https://python-all.ru/3.11/library/stdtypes.html#str)), либо двоичные данные ([`bytes`](https://python-all.ru/3.11/library/stdtypes.html#bytes)). Это определяется аргументом *encoding*. Если *encoding* равен `"unicode"`, результатом будет строка; в противном случае – двоичные данные. Учтите, что это может конфликтовать с типом *file*, если это открытый [файловый объект](https://python-all.ru/3.11/glossary.html#term-file-object); убедитесь, что не пытаетесь записать строку в двоичный поток и наоборот.785786Изменено в версии 3.4: Добавлен параметр *short\_empty\_elements*.787788Изменено в версии 3.8: Метод [`write()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ElementTree.write) теперь сохраняет порядок атрибутов, заданный пользователем.789790Это XML-файл, который будет обрабатываться:791792```python793<html>794    <head>795        <title>Example page</title>796    </head>797    <body>798        <p>Moved to <a href="http://example.org/">example.org</a>799        or <a href="http://example.com/">example.com</a>.</p>800    </body>801</html>802```803804Пример изменения атрибута «target» каждой ссылки в первом абзаце:805806```python807>>> from xml.etree.ElementTree import ElementTree808>>> tree = ElementTree()809>>> tree.parse("index.xhtml")810<Element 'html' at 0xb77e6fac>811>>> p = tree.find("body/p")     # Находит первое вхождение тега p в body812>>> p813<Element 'p' at 0xb77ec26c>814>>> links = list(p.iter("a"))   # Возвращает список всех ссылок815>>> links816[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]817>>> for i in links:             # Перебирает все найденные ссылки818...     i.attrib["target"] = "blank"819>>> tree.write("output.xhtml")820```821822### Объекты QName823824#### `class xml.etree.ElementTree.QName(text_or_uri, tag=None)`825826Обёртка QName. Используется для обёртывания значения атрибута QName, чтобы при выводе обеспечить правильную обработку пространств имён. *text\_or\_uri* – строка, содержащая значение QName в форме {uri}local, или, если передан аргумент tag, – URI-часть QName. Если передан *tag*, то первый аргумент интерпретируется как URI, а этот аргумент – как локальное имя. Экземпляры [`QName`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.QName) непрозрачны.827828### Объекты TreeBuilder829830#### `class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)`831832Универсальный построитель структуры элементов. Этот построитель преобразует последовательность вызовов методов start, data, end, comment и pi в правильно сформированную структуру элементов. Этот класс можно использовать для построения структуры элементов с помощью собственного XML-парсера или парсера для какого-либо другого XML-подобного формата.833834*element\_factory*, если задан, должен быть вызываемым объектом, принимающим два позиционных аргумента: tag и словарь атрибутов. Ожидается, что он вернёт новый экземпляр элемента.835836Функции *comment\_factory* и *pi\_factory*, если заданы, должны вести себя как функции [`Comment()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Comment) и [`ProcessingInstruction()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.ProcessingInstruction) для создания комментариев и инструкций обработки. Если они не заданы, используются фабрики по умолчанию. Если *insert\_comments* и/или *insert\_pis* равно true, комментарии/инструкции обработки будут вставлены в дерево, если они появляются внутри корневого элемента (но не вне его).837838#### `close()`839840Сбрасывает буферы построителя и возвращает элемент верхнего уровня документа. Возвращает экземпляр [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element).841842#### `data(data)`843844Добавляет текст в текущий элемент. *data* является строкой. Это должна быть либо байтовая строка, либо строка Unicode.845846#### `end(tag)`847848Закрывает текущий элемент. *tag* – имя элемента. Возвращает закрытый элемент.849850#### `start(tag, attrs)`851852Открывает новый элемент. *tag* – имя элемента. *attrs* – словарь, содержащий атрибуты элемента. Возвращает открытый элемент.853854#### `comment(text)`855856Создаёт комментарий с заданным *text*. Если `insert_comments` равно true, он также будет добавлен в дерево.857858Новое в версии 3.8.859860#### `pi(target, text)`861862Создаёт инструкцию обработки с заданным именем *target* и *text*. Если `insert_pis` равно true, она также будет добавлена в дерево.863864Новое в версии 3.8.865866Кроме того, пользовательский объект [`TreeBuilder`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder) может предоставлять следующие методы:867868#### `doctype(name, pubid, system)`869870Обрабатывает объявление doctype. *name* – имя doctype. *pubid* – публичный идентификатор. *system* – системный идентификатор. Этот метод не существует в классе [`TreeBuilder`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder) по умолчанию.871872Новое в версии 3.2.873874#### `start_ns(prefix, uri)`875876Вызывается всякий раз, когда парсер встречает новое объявление пространства имён, перед колбэком `start()` для открывающего элемента, который его определяет. *prefix* равен `''` для пространства имён по умолчанию и имени объявленного префикса пространства имён в противном случае. *uri* – URI пространства имён.877878Новое в версии 3.8.879880#### `end_ns(prefix)`881882Вызывается после колбэка `end()` элемента, который объявил отображение префикса пространства имён, с именем *prefix*, вышедшего из области видимости.883884Новое в версии 3.8.885886#### `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)`887888Писатель [C14N 2.0](https://python-all.ru/3.11/library/xml.etree.elementtree.html). Аргументы такие же, как у функции [`canonicalize()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.canonicalize). Этот класс не строит дерево, а преобразует события колбэков напрямую в сериализованную форму с помощью функции *write*.889890Новое в версии 3.8.891892### Объекты XMLParser893894#### `class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)`895896Этот класс является низкоуровневым строительным блоком модуля. Он использует [`xml.parsers.expat`](https://python-all.ru/3.11/library/pyexpat.html#module-xml.parsers.expat) для эффективного, основанного на событиях разбора XML. В него можно по частям подавать XML-данные с помощью метода [`feed()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.feed), а события разбора преобразуются в push-API путём вызова колбэков на объекте *target*. Если *target* опущен, используется стандартный [`TreeBuilder`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder). Если задан *encoding* [\[1\]](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id9), значение переопределяет кодировку, указанную в XML-файле.897898Изменено в версии 3.8: Параметры теперь [только по ключевым словам](https://python-all.ru/3.11/glossary.html#keyword-only-parameter). Аргумент *html* больше не поддерживается.899900#### `close()`901902Завершает передачу данных парсеру. Возвращает результат вызова метода `close()` *цели*, переданной при создании; по умолчанию это корневой элемент документа.903904#### `feed(data)`905906Передает данные парсеру. *data* – это закодированные данные.907908#### `flush()`909910Запускает разбор любых ранее переданных, но еще не разобранных данных. Это может использоваться для обеспечения более оперативной обратной связи, особенно с Expat \>=2.6.0. Реализация [`flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.flush) временно отключает отложенный переразбор в Expat (если он включен) и запускает переразбор. Отключение отложенного переразбора имеет последствия для безопасности; подробнее см. [`xml.parsers.expat.xmlparser.SetReparseDeferralEnabled()`](https://python-all.ru/3.11/library/pyexpat.html#xml.parsers.expat.xmlparser.SetReparseDeferralEnabled).911912Обратите внимание, что [`flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.flush) был перенесен в некоторые предыдущие версии CPython как исправление безопасности. Проверяйте доступность [`flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.flush) с помощью [`hasattr()`](https://python-all.ru/3.11/library/functions.html#hasattr), если используется в коде, работающем в разных версиях Python.913914Новое в версии 3.11.9.915916[`XMLParser.feed()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.feed) вызывает метод *цели* `start(tag, attrs_dict)` для каждого открывающего тега, метод `end(tag)` – для каждого закрывающего тега, а данные обрабатываются методом `data(data)`. Дополнительные поддерживаемые методы колбэков см. в классе [`TreeBuilder`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.TreeBuilder). [`XMLParser.close()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.close) вызывает метод *цели* `close()`. [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser) может использоваться не только для построения древовидной структуры. Ниже приведен пример подсчета максимальной глубины XML-файла:917918```python919>>> from xml.etree.ElementTree import XMLParser920>>> class MaxDepth:                     # Целевой объект парсера921...     maxDepth = 0922...     depth = 0923...     def start(self, tag, attrib):   # Вызывается для каждого открывающего тега.924...         self.depth += 1925...         if self.depth > self.maxDepth:926...             self.maxDepth = self.depth927...     def end(self, tag):             # Вызывается для каждого закрывающего тега.928...         self.depth -= 1929...     def data(self, data):930...         pass            # С данными ничего делать не нужно.931...     def close(self):    # Вызывается, когда все данные проанализированы.932...         return self.maxDepth933...934>>> target = MaxDepth()935>>> parser = XMLParser(target=target)936>>> exampleXml = """937... <a>938...   <b>939...   </b>940...   <b>941...     <c>942...       <d>943...       </d>944...     </c>945...   </b>946... </a>"""947>>> parser.feed(exampleXml)948>>> parser.close()9494950```951952### Объекты XMLPullParser953954#### `class xml.etree.ElementTree.XMLPullParser(events=None)`955956Pull-парсер, подходящий для неблокирующих приложений. Его API на стороне ввода похож на API [`XMLParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser), но вместо передачи вызовов целевому колбэку [`XMLPullParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser) собирает внутренний список событий разбора и позволяет читать из него. *events* – это последовательность событий для отчета. Поддерживаются строки событий: `"start"`, `"end"`, `"comment"`, `"pi"`, `"start-ns"` и `"end-ns"` (события "ns" используются для получения подробной информации о пространствах имен). Если *events* опущен, сообщаются только события `"end"`.957958#### `feed(data)`959960Передает парсеру данные в виде байтов.961962#### `flush()`963964Запускает разбор любых ранее переданных, но еще не разобранных данных. Это может использоваться для обеспечения более оперативной обратной связи, особенно с Expat \>=2.6.0. Реализация [`flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.flush) временно отключает отложенный переразбор в Expat (если он включен) и запускает переразбор. Отключение отложенного переразбора имеет последствия для безопасности; подробнее см. [`xml.parsers.expat.xmlparser.SetReparseDeferralEnabled()`](https://python-all.ru/3.11/library/pyexpat.html#xml.parsers.expat.xmlparser.SetReparseDeferralEnabled).965966Обратите внимание, что [`flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.flush) был перенесен в некоторые предыдущие версии CPython как исправление безопасности. Проверяйте доступность [`flush()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.flush) с помощью [`hasattr()`](https://python-all.ru/3.11/library/functions.html#hasattr), если используется в коде, работающем в разных версиях Python.967968Новое в версии 3.11.9.969970#### `close()`971972Сигнализирует парсеру, что поток данных завершен. В отличие от [`XMLParser.close()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLParser.close), этот метод всегда возвращает [`None`](https://python-all.ru/3.11/library/constants.html#None). Любые события, еще не извлеченные на момент закрытия парсера, все еще можно прочитать с помощью [`read_events()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.read_events).973974#### `read_events()`975976Возвращает итератор по событиям, которые были обнаружены в данных, переданных парсеру. Итератор выдает пары `(event, elem)`, где *event* – строка, представляющая тип события (например, `"end"`), а *elem* – обнаруженный объект [`Element`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.Element) или другое контекстное значение, как указано ниже.977978- `start`, `end`: текущий элемент.979- `comment`, `pi`: текущий комментарий / инструкция по обработке.980- `start-ns`: кортеж `(prefix, uri)`, именующий объявленное пространство имен.981- `end-ns`: [`None`](https://python-all.ru/3.11/library/constants.html#None) (может измениться в будущей версии).982983События, предоставленные в предыдущем вызове [`read_events()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.read_events), не будут возвращены снова. События потребляются из внутренней очереди только при извлечении из итератора, поэтому несколько читателей, параллельно выполняющих итерацию по итераторам, полученным из [`read_events()`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser.read_events), будут иметь непредсказуемые результаты.984985> **Примечание**986>987> [`XMLPullParser`](https://python-all.ru/3.11/library/xml.etree.elementtree.html#xml.etree.ElementTree.XMLPullParser) гарантирует только, что при генерации события "start" был обнаружен символ "\>" открывающего тега, поэтому атрибуты определены, но содержимое атрибутов text и tail на этом этапе не определено. То же самое относится и к дочерним элементам: они могут присутствовать, а могут и нет.988>989> Если нужен полностью заполненный элемент, используйте события "end".990991Новое в версии 3.4.992993Изменено в версии 3.8: Были добавлены события `comment` и `pi`.994995### Исключения996997#### `class xml.etree.ElementTree.ParseError`998999Ошибка разбора XML, возникающая при сбое разбора в различных методах разбора этого модуля. Строковое представление экземпляра этого исключения будет содержать понятное пользователю сообщение об ошибке. Кроме того, будут доступны следующие атрибуты:10001001#### `code`10021003Числовой код ошибки от парсера expat. Список кодов ошибок и их значений см. в документации [`xml.parsers.expat`](https://python-all.ru/3.11/library/pyexpat.html#module-xml.parsers.expat).10041005#### `position`10061007Кортеж из номеров строки *line* и столбца *column*, указывающий, где произошла ошибка.10081009Сноски10101011\[1\]10121013([1](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id1),[2](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id2),[3](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id6),[4](https://python-all.ru/3.11/library/xml.etree.elementtree.html#id8))10141015Строка кодировки, включенная в вывод XML, должна соответствовать соответствующим стандартам. Например, "UTF-8" допустима, а "UTF8" – нет. См. [https://www.w3.org/TR/2006/REC-xml11-20060816/#NT-EncodingDecl](https://python-all.ru/3.11/library/xml.etree.elementtree.html) и [https://www.iana.org/assignments/character-sets/character-sets.xhtml](https://python-all.ru/3.11/library/xml.etree.elementtree.html).1016