xml.etree.ElementTree — API XML ElementTree
Исходный код: Lib/xml/etree/ElementTree.py
Модуль xml.etree.ElementTree реализует простой и эффективный API для разбора и создания данных XML.
Изменено в версии 3.3: Этот модуль будет использовать быструю реализацию, если она доступна.
Устарело начиная с версии 3.3: Модуль xml.etree.cElementTree устарел.
Примечание
Если вам нужно разобрать недоверенные или неаутентифицированные данные, см. раздел Безопасность XML.
Руководство
Это краткое руководство по использованию xml.etree.ElementTree (сокращённо — ET). Его цель — показать некоторые основные строительные блоки и концепции модуля.
Дерево XML и элементы
XML по своей природе является иерархическим форматом данных, и наиболее естественный способ его представления — дерево. ET содержит два класса для этой цели: ElementTree представляет весь XML-документ в виде дерева, а Element представляет один узел в этом дереве. Операции со всем документом (чтение из файлов и запись в них) обычно выполняются на уровне ElementTree. Операции с отдельным XML-элементом и его дочерними элементами выполняются на уровне Element.
Разбор XML
В качестве примера данных для этого раздела мы будем использовать вымышленный XML-документ country_data.xml:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
Эти данные можно импортировать, прочитав их из файла:
import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()
Или непосредственно из строки:
root = ET.fromstring(country_data_as_string)
fromstring() разбирает XML непосредственно из строки в объект Element, который является корневым элементом разобранного дерева. Другие функции разбора могут создавать объект ElementTree. Уточните это в документации.
Как объект Element, root имеет тег и словарь атрибутов:
>>> root.tag
'data'
>>> root.attrib
{}
У него также есть дочерние узлы, по которым можно выполнить итерацию:
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
Дочерние узлы могут быть вложенными, и к конкретным дочерним узлам можно обращаться по индексу:
>>> root[0][1].text '2008'
Примечание
Не все элементы входных данных XML попадут в разобранное дерево в качестве элементов. В настоящее время этот модуль пропускает все XML-комментарии, инструкции обработки и объявления типа документа во входных данных. Тем не менее деревья, созданные с помощью API этого модуля, а не путём разбора текста XML, могут содержать комментарии и инструкции обработки; они будут включены в создаваемый XML-вывод. Доступ к объявлению типа документа можно получить, передав пользовательский экземпляр TreeBuilder конструктору XMLParser.
Pull API для неблокирующего разбора
Большинство функций разбора, предоставляемых этим модулем, должны прочитать весь документ целиком, прежде чем вернуть результат. Можно использовать XMLParser и постепенно передавать ему данные, но это push API, которое вызывает методы целевого объекта обратного вызова; такой подход слишком низкоуровневый и неудобный для большинства задач. Иногда пользователю нужно разбирать XML постепенно, без блокирующих операций, и при этом пользоваться удобством полностью сформированных объектов Element.
Самый мощный инструмент для этого — XMLPullParser. Для получения данных XML ему не требуется блокирующее чтение: вместо этого данные передаются постепенно с помощью вызовов XMLPullParser.feed(). Чтобы получить разобранные элементы XML, вызовите XMLPullParser.read_events(). Вот пример:
>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
... print(event)
... print(elem.tag, 'text=', elem.text)
...
end
mytag text= sometext more text
Очевидный вариант использования — приложения, работающие в неблокирующем режиме, в которых данные XML поступают из сокета или постепенно считываются с какого-либо устройства хранения. В таких случаях блокирующее чтение недопустимо.
Из-за своей гибкости XMLPullParser может быть неудобен для более простых задач. Если вы не возражаете против блокировки приложения при чтении данных XML, но хотите разбирать их постепенно, ознакомьтесь с iterparse(). Этот метод может быть полезен при чтении большого XML-документа, который не хочется целиком хранить в памяти.
Если требуется немедленная обратная связь через события, вызов метода XMLPullParser.flush() поможет сократить задержку; обязательно изучите соответствующие примечания по безопасности.
Поиск интересующих элементов
У Element есть несколько полезных методов для рекурсивного перебора всего поддерева (его дочерних элементов, их дочерних элементов и так далее). Например, Element.iter():
>>> for neighbor in root.iter('neighbor'):
... print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
Element.findall() находит только элементы с указанным тегом, которые являются непосредственными дочерними элементами текущего элемента. Element.find() находит первый дочерний элемент с определённым тегом, а Element.text предоставляет доступ к текстовому содержимому элемента. Element.get() предоставляет доступ к атрибутам элемента:
>>> for country in root.findall('country'):
... rank = country.find('rank').text
... name = country.get('name')
... print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68
Более сложные условия поиска элементов можно задать с помощью XPath.
Изменение XML-файла
ElementTree предоставляет простой способ создания XML-документов и их записи в файлы. Для этого предназначен метод ElementTree.write().
После создания объект Element можно изменять напрямую, меняя его поля (например, Element.text), добавляя и изменяя атрибуты (метод Element.set()), а также добавляя новые дочерние элементы (например, с помощью Element.append()).
Предположим, что мы хотим увеличить ранг каждой страны на единицу и добавить атрибут updated к элементу ранга:
>>> for rank in root.iter('rank'):
... new_rank = int(rank.text) + 1
... rank.text = str(new_rank)
... rank.set('updated', 'yes')
...
>>> tree.write('output.xml')
Теперь наш XML выглядит так:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
Удалять элементы можно с помощью Element.remove(). Предположим, что мы хотим удалить все страны с рангом выше 50:
>>> for country in root.findall('country'):
... # using root.findall() to avoid removal during traversal
... rank = int(country.find('rank').text)
... if rank > 50:
... root.remove(country)
...
>>> tree.write('output.xml')
Обратите внимание, что одновременное изменение данных во время итерации может привести к проблемам, как и при обходе и изменении списков или словарей Python. Поэтому в примере сначала с помощью root.findall() собираются все подходящие элементы, и только после этого выполняется итерация по списку найденных элементов.
Теперь наш XML выглядит так:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
</data>
Создание XML-документов
Функция SubElement() также предоставляет удобный способ создания новых дочерних элементов для заданного элемента:
>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>
Разбор XML с пространствами имён
Если входные данные XML содержат пространства имён, теги и атрибуты с префиксами в форме prefix:sometag преобразуются в {uri}sometag, где префикс заменяется полным URI. Кроме того, если задано пространство имён по умолчанию, этот полный URI добавляется перед всеми тегами без префикса.
Вот пример XML с двумя пространствами имён: одно имеет префикс «fictional», а другое используется как пространство имён по умолчанию:
<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
xmlns="http://people.example.com">
<actor>
<name>John Cleese</name>
<fictional:character>Lancelot</fictional:character>
<fictional:character>Archie Leach</fictional:character>
</actor>
<actor>
<name>Eric Idle</name>
<fictional:character>Sir Robin</fictional:character>
<fictional:character>Gunther</fictional:character>
<fictional:character>Commander Clement</fictional:character>
</actor>
</actors>
Один из способов поиска и изучения этого примера XML — вручную добавить URI к каждому тегу или атрибуту в xpath для find() или findall():
root = fromstring(xml_text)
for actor in root.findall('{http://people.example.com}actor'):
name = actor.find('{http://people.example.com}name')
print(name.text)
for char in actor.findall('{http://characters.example.com}character'):
print(' |-->', char.text)
Более удобный способ поиска в примере XML с пространствами имён — создать словарь со своими префиксами и использовать их в функциях поиска:
ns = {'real_person': 'http://people.example.com',
'role': 'http://characters.example.com'}
for actor in root.findall('real_person:actor', ns):
name = actor.find('real_person:name', ns)
print(name.text)
for char in actor.findall('role:character', ns):
print(' |-->', char.text)
Оба подхода дают следующий результат:
John Cleese |--> Lancelot |--> Archie Leach Eric Idle |--> Sir Robin |--> Gunther |--> Commander Clement
Поддержка XPath
Этот модуль предоставляет ограниченную поддержку выражений XPath для поиска элементов в дереве. Цель — поддержать небольшое подмножество сокращённого синтаксиса; полноценный механизм XPath выходит за рамки этого модуля.
Пример
Вот пример, демонстрирующий некоторые возможности XPath в этом модуле. Мы будем использовать XML-документ countrydata из раздела Разбор XML:
import xml.etree.ElementTree as ET
root = ET.fromstring(countrydata)
# Top-level elements
root.findall(".")
# All 'neighbor' grand-children of 'country' children of the top-level
# elements
root.findall("./country/neighbor")
# Nodes with name='Singapore' that have a 'year' child
root.findall(".//year/..[@name='Singapore']")
# 'year' nodes that are children of nodes with name='Singapore'
root.findall(".//*[@name='Singapore']/year")
# All 'neighbor' nodes that are the second child of their parent
root.findall(".//neighbor[2]")
Для XML с пространствами имён используйте обычную запись с квалифицированным именем {namespace}tag:
# All dublin-core "title" tags in the document
root.findall(".//{http://purl.org/dc/elements/1.1/}title")
Поддерживаемый синтаксис XPath
Синтаксис | Значение |
|---|---|
|
Выбирает все дочерние элементы с указанным тегом. Например, Изменено в версии 3.8: Добавлена поддержка подстановочных символов-звёздочек. |
| Выбирает все дочерние элементы, включая комментарии и инструкции обработки. Например, |
| Выбирает текущий узел. Это в основном полезно в начале пути, чтобы указать, что путь относительный. |
| Выбирает все подэлементы на всех уровнях ниже текущего элемента. Например, |
| Выбирает родительский элемент. Возвращает |
| Выбирает все элементы, у которых есть указанный атрибут. |
| Выбирает все элементы, у которых указанный атрибут имеет заданное значение. Значение не может содержать кавычки. |
|
Выбирает все элементы, у которых указанный атрибут не имеет заданного значения. Значение не может содержать кавычки. Добавлено в версии 3.10. |
| Выбирает все элементы, у которых есть дочерний элемент с именем |
|
Выбирает все элементы, полное текстовое содержимое которых, включая потомков, совпадает с заданным Добавлено в версии 3.7. |
|
Выбирает все элементы, полное текстовое содержимое которых, включая потомков, не совпадает с заданным Добавлено в версии 3.10. |
| Выбирает все элементы, у которых есть дочерний элемент с именем |
|
Выбирает все элементы, у которых есть дочерний элемент с именем Добавлено в версии 3.10. |
| Выбирает все элементы, находящиеся в указанной позиции. Позиция может быть целым числом (1 — первая позиция), выражением |
Предикатам (выражениям в квадратных скобках) должно предшествовать имя тега, звёздочка или другой предикат. Предикатам position должно предшествовать имя тега.
Справочник
Функции
-
xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options) -
Функция преобразования C14N 2.0.
Канонизация — это способ нормализации вывода XML, позволяющий выполнять побайтовые сравнения и создавать цифровые подписи. Она ограничивает свободу действий сериализаторов XML и вместо этого создает более строгую форму представления XML. Основные ограничения касаются размещения объявлений пространств имен, порядка атрибутов и игнорируемых пробелов.
Эта функция принимает в качестве входных данных строку XML (xml_data), путь к файлу или файловый объект (from_file), преобразует данные в каноническую форму и записывает их с помощью файлового объекта out (или объекта, подобного файлу), если он указан, либо возвращает текстовую строку, если он не указан. В выходной файл записывается текст, а не байты. Поэтому его следует открывать в текстовом режиме с кодировкой
utf-8.Типичные варианты использования:
xml_data = "<root>...</root>" print(canonicalize(xml_data)) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(xml_data, out=out_file) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(from_file="inputfile.xml", out=out_file)Параметры конфигурации options:
- with_comments: установите значение true, чтобы включить комментарии (по умолчанию: false)
-
- strip_text: установите значение true, чтобы удалить пробелы перед текстом и после него
-
(по умолчанию: false)
-
- rewrite_prefixes: установите значение true, чтобы заменить префиксы пространств имен на «n{number}»
-
(по умолчанию: false)
-
- qname_aware_tags: набор имен тегов, учитывающих qname, в которых префиксы
-
следует заменять в текстовом содержимом (по умолчанию: пустой набор)
-
- qname_aware_attrs: набор имен атрибутов, учитывающих qname, в которых префиксы
-
следует заменять в текстовом содержимом (по умолчанию: пустой набор)
- exclude_attrs: набор имен атрибутов, которые не следует сериализовать
- exclude_tags: набор имен тегов, которые не следует сериализовать
В приведенном выше списке параметров «набор» означает любую коллекцию или итерируемый объект строк; порядок не имеет значения.
Добавлено в версии 3.8.
-
xml.etree.ElementTree.Comment(text=None) -
Фабрика элементов комментариев. Эта фабричная функция создает специальный элемент, который стандартный сериализатор преобразует в комментарий XML. Строка комментария может быть байтовой строкой или строкой Unicode. text — это строка, содержащая текст комментария. Возвращает экземпляр элемента, представляющий комментарий.
Обратите внимание, что
XMLParserпропускает комментарии во входных данных, а не создает для них объекты комментариев.ElementTreeбудет содержать узлы комментариев, только если они были вставлены в дерево с помощью одного из методовElement.
-
xml.etree.ElementTree.dump(elem) -
Записывает дерево элементов или структуру элементов в sys.stdout. Эту функцию следует использовать только для отладки.
Точный формат вывода зависит от реализации. В этой версии данные записываются как обычный файл XML.
elem — это дерево элементов или отдельный элемент.
Изменено в версии 3.8: Теперь функция
dump()сохраняет порядок атрибутов, заданный пользователем.
-
xml.etree.ElementTree.fromstring(text, parser=None) -
Разбирает фрагмент XML из строковой константы. То же, что и
XML(). text — это строка, содержащая данные XML. parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализаторXMLParser. Возвращает экземплярElement.
-
xml.etree.ElementTree.fromstringlist(sequence, parser=None) -
Разбирает документ XML из последовательности строковых фрагментов. sequence — это список или другая последовательность, содержащая фрагменты данных XML. parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор
XMLParser. Возвращает экземплярElement.Добавлено в версии 3.2.
-
xml.etree.ElementTree.indent(tree, space=' ', level=0) -
Добавляет пробелы в поддерево, чтобы визуально отформатировать дерево с отступами. Это можно использовать для создания XML с красивым форматированием. tree может быть элементом или ElementTree. space — строка пробелов, которая будет вставляться для каждого уровня отступа; по умолчанию используются два пробела. Чтобы форматировать с отступами частичные поддеревья внутри уже отформатированного дерева, передайте начальный уровень отступа в параметре level.
Добавлено в версии 3.9.
-
xml.etree.ElementTree.iselement(element) -
Проверяет, выглядит ли объект как допустимый объект элемента. element — это экземпляр элемента. Возвращает
True, если это объект элемента.
-
xml.etree.ElementTree.iterparse(source, events=None, parser=None) -
Постепенно разбирает фрагмент XML в дерево элементов и сообщает пользователю о ходе выполнения. source — имя файла или файловый объект, содержащий данные XML. events — последовательность событий, о которых нужно сообщать. Поддерживаются строки
"start","end","comment","pi","start-ns"и"end-ns"(события «ns» используются для получения подробной информации о пространствах имен). Если events не указан, сообщаются только события"end". parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализаторXMLParser. parser должен быть подклассомXMLParserи может использовать в качестве целевого объекта только стандартныйTreeBuilder. Возвращает итератор, предоставляющий пары(event, elem); у него есть атрибутroot, ссылающийся на корневой элемент результирующего дерева XML после полного чтения source. У итератора есть методclose(), который закрывает внутренний файловый объект, если source — это имя файла.Обратите внимание: хотя
iterparse()строит дерево постепенно, он выполняет блокирующее чтение из source (или указанного в нем файла). Поэтому он не подходит для приложений, в которых невозможно выполнять блокирующее чтение. Для полностью неблокирующего разбора см.XMLPullParser.Примечание
iterparse()гарантирует лишь то, что при выдаче события «start» он увидел символ «>» открывающего тега, поэтому атрибуты уже определены, но содержимое атрибутов text и tail в этот момент не определено. То же относится к дочерним элементам: они могут присутствовать, а могут и отсутствовать.Если вам нужен полностью заполненный элемент, используйте события «end».
Устарел начиная с версии 3.4: Аргумент parser.
Изменено в версии 3.8: Добавлены события
commentиpi.Изменено в версии 3.13: Добавлен метод
close().
-
xml.etree.ElementTree.parse(source, parser=None) -
Разбирает фрагмент XML в дерево элементов. source — имя файла или файловый объект, содержащий данные XML. parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор
XMLParser. Возвращает экземплярElementTree.
-
xml.etree.ElementTree.ProcessingInstruction(target, text=None) -
Фабрика элементов PI. Эта фабричная функция создает специальный элемент, который будет сериализован как инструкция обработки XML. target — строка, содержащая цель PI. text — строка, содержащая содержимое PI, если оно указано. Возвращает экземпляр элемента, представляющий инструкцию обработки.
Обратите внимание, что
XMLParserпропускает инструкции обработки во входных данных, а не создает для них объекты PI.ElementTreeбудет содержать узлы инструкций обработки, только если они были вставлены в дерево с помощью одного из методовElement.
-
xml.etree.ElementTree.register_namespace(prefix, uri) -
Регистрирует префикс пространства имен. Реестр является глобальным; все существующие соответствия для указанного префикса или URI пространства имен будут удалены. prefix — префикс пространства имен. uri — URI пространства имен. Теги и атрибуты в этом пространстве имен будут сериализованы с указанным префиксом, если это возможно.
Добавлено в версии 3.2.
-
xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra) -
Фабрика вложенных элементов. Эта функция создает экземпляр элемента и добавляет его к существующему элементу.
Имя элемента, имена атрибутов и значения атрибутов могут быть байтовыми строками или строками Unicode. parent — родительский элемент. tag — имя вложенного элемента. attrib — необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные как именованные аргументы. Возвращает экземпляр элемента.
-
xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True) -
Создает строковое представление элемента XML, включая все вложенные элементы. element — это экземпляр
Element. encoding [1] — кодировка выходных данных (по умолчанию US-ASCII). Используйтеencoding="unicode", чтобы создать строку Unicode (иначе создается байтовая строка). method — это"xml","html"или"text"(по умолчанию"xml"). Параметры xml_declaration, default_namespace и short_empty_elements имеют тот же смысл, что и вElementTree.write(). Возвращает (опционально) закодированную строку, содержащую данные XML.Изменено в версии 3.4: Добавлен параметр short_empty_elements.
Изменено в версии 3.8: Добавлены параметры xml_declaration и default_namespace.
Изменено в версии 3.8: Теперь функция
tostring()сохраняет порядок атрибутов, заданный пользователем.
-
xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True) -
Создает строковое представление элемента XML, включая все вложенные элементы. element — это экземпляр
Element. encoding [1] — кодировка выходных данных (по умолчанию US-ASCII). Используйтеencoding="unicode", чтобы создать строку Unicode (иначе создается байтовая строка). method — это"xml","html"или"text"(по умолчанию"xml"). Параметры xml_declaration, default_namespace и short_empty_elements имеют тот же смысл, что и вElementTree.write(). Возвращает список (опционально) закодированных строк, содержащих данные XML. Определенный порядок не гарантируется, за исключением того, чтоb"".join(tostringlist(element)) == tostring(element).Добавлено в версии 3.2.
Изменено в версии 3.4: Добавлен параметр short_empty_elements.
Изменено в версии 3.8: Добавлены параметры xml_declaration и default_namespace.
Изменено в версии 3.8: Теперь функция
tostringlist()сохраняет порядок атрибутов, заданный пользователем.
-
xml.etree.ElementTree.XML(text, parser=None) -
Разбирает фрагмент XML из строковой константы. Эту функцию можно использовать для встраивания «литералов XML» в код Python. text — это строка, содержащая данные XML. parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор
XMLParser. Возвращает экземплярElement.
-
xml.etree.ElementTree.XMLID(text, parser=None) -
Разбирает фрагмент XML из строковой константы, а также возвращает словарь, сопоставляющий идентификаторы элементов с элементами. text — это строка, содержащая данные XML. parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор
XMLParser. Возвращает кортеж, содержащий экземплярElementи словарь.
Поддержка XInclude
Этот модуль предоставляет ограниченную поддержку директив XInclude с помощью вспомогательного модуля xml.etree.ElementInclude. Этот модуль можно использовать для вставки поддеревьев и текстовых строк в деревья элементов на основе информации из дерева.
Пример
В этом примере демонстрируется использование модуля XInclude. Чтобы включить документ XML в текущий документ, используйте элемент {http://www.w3.org/2001/XInclude}include, задайте для атрибута parse значение "xml" и укажите включаемый документ с помощью атрибута href.
<?xml version="1.0"?> <document xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="source.xml" parse="xml" /> </document>
По умолчанию атрибут href интерпретируется как имя файла. Это поведение можно изменить с помощью пользовательских загрузчиков. Также обратите внимание, что стандартный вспомогательный модуль не поддерживает синтаксис XPointer.
Чтобы обработать этот файл, загрузите его обычным способом и передайте корневой элемент модулю xml.etree.ElementTree:
from xml.etree import ElementTree, ElementInclude
tree = ElementTree.parse("document.xml")
root = tree.getroot()
ElementInclude.include(root)
Модуль ElementInclude заменяет элемент {http://www.w3.org/2001/XInclude}include корневым элементом документа source.xml. Результат может выглядеть примерно так:
<document xmlns:xi="http://www.w3.org/2001/XInclude"> <para>This is a paragraph.</para> </document>
Если атрибут parse не указан, по умолчанию используется значение «xml». Атрибут href является обязательным.
Чтобы включить текстовый документ, используйте элемент {http://www.w3.org/2001/XInclude}include и задайте для атрибута parse значение «text»:
<?xml version="1.0"?> <document xmlns:xi="http://www.w3.org/2001/XInclude"> Copyright (c) <xi:include href="year.txt" parse="text" />. </document>
Результат может выглядеть примерно так:
<document xmlns:xi="http://www.w3.org/2001/XInclude"> Copyright (c) 2003. </document>
Справочник
Функции
-
xml.etree.ElementInclude.default_loader(href, parse, encoding=None) -
Загрузчик по умолчанию. Этот загрузчик по умолчанию считывает включаемый ресурс с диска. href — это URL. parse задаёт режим разбора: «xml» или «text». encoding — необязательная кодировка текста. Если она не задана, используется
utf-8. Возвращает развернутый ресурс. Если режим разбора —"xml", это экземплярElement. Если режим разбора —"text", это строка. Если загрузчику не удаётся выполнить загрузку, он может вернутьNoneили вызвать исключение.
-
xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6) -
Эта функция на месте разворачивает директивы XInclude в дереве, на которое указывает elem. elem — это либо корневой
Element, либо экземплярElementTree, в котором выполняется поиск такого элемента. loader — необязательный загрузчик ресурсов. Если он не указан, по умолчанию используетсяdefault_loader(). Если он указан, это должен быть вызываемый объект, реализующий тот же интерфейс, что иdefault_loader(). base_url — базовый URL исходного файла, используемый для разрешения относительных ссылок на включаемые файлы. max_depth — максимальное количество рекурсивных включений. Ограничение снижает риск разрастания вредоносного содержимого. ПередайтеNone, чтобы отключить ограничение.Изменено в версии 3.9: Добавлены параметры base_url и max_depth.
Объекты Element
-
class xml.etree.ElementTree.Element(tag, attrib={}, **extra) -
Класс Element. Этот класс определяет интерфейс Element и предоставляет эталонную реализацию этого интерфейса.
Имя элемента, имена атрибутов и значения атрибутов могут быть либо байтовыми строками, либо строками Unicode. tag — имя элемента. attrib — необязательный словарь с атрибутами элемента. extra содержит дополнительные атрибуты, переданные в виде именованных аргументов.
-
tag -
Строка, указывающая, какой тип данных представляет этот элемент (другими словами, тип элемента).
-
text -
tail -
Эти атрибуты можно использовать для хранения дополнительных данных, связанных с элементом. Обычно их значения — строки, но это могут быть любые объекты, специфичные для приложения. Если элемент создан из XML-файла, атрибут text содержит либо текст между открывающим тегом элемента и его первым дочерним элементом или закрывающим тегом, либо
None, а атрибут tail содержит либо текст между закрывающим тегом элемента и следующим тегом, либоNone. Для XML-данных<a><b>1<c>2<d/>3</c></b>4</a>
элемент a имеет
Noneв атрибутах text и tail, элемент b имеет text"1"и tail"4", элемент c имеет text"2"и tailNone, а элемент d имеет textNoneи tail"3".Чтобы получить внутренний текст элемента, см.
itertext(), например"".join(element.itertext()).Приложения могут хранить в этих атрибутах произвольные объекты.
-
attrib -
Словарь, содержащий атрибуты элемента. Обратите внимание: хотя значение attrib всегда является настоящим изменяемым словарём Python, реализация ElementTree может использовать другое внутреннее представление и создавать словарь только по запросу. Чтобы воспользоваться такими реализациями, по возможности используйте приведённые ниже методы словаря.
Для работы с атрибутами элемента подходят следующие методы, подобные методам словаря.
-
clear() -
Сбрасывает элемент. Эта функция удаляет все дочерние элементы, очищает все атрибуты и устанавливает атрибуты text и tail в значение
None.
-
get(key, default=None) -
Получает атрибут элемента с именем key.
Возвращает значение атрибута или default, если атрибут не найден.
-
items() -
Возвращает атрибуты элемента в виде последовательности пар (имя, значение). Атрибуты возвращаются в произвольном порядке.
-
keys() -
Возвращает имена атрибутов элемента в виде списка. Имена возвращаются в произвольном порядке.
-
set(key, value) -
Устанавливает для атрибута элемента key значение value.
Для работы с дочерними элементами элемента (подэлементами) предназначены следующие методы.
-
append(subelement) -
Добавляет элемент subelement в конец внутреннего списка подэлементов этого элемента. Вызывает
TypeError, если subelement не являетсяElement.
-
extend(subelements) -
Добавляет subelements из итерируемого объекта элементов. Вызывает
TypeError, если подэлемент не являетсяElement.Добавлено в версии 3.2.
-
find(match, namespaces=None) -
Находит первый подэлемент, соответствующий match. match может быть именем тега или путём. Возвращает экземпляр элемента или
None. namespaces — необязательное сопоставление префиксов пространств имён с полными именами. Передайте''в качестве префикса, чтобы перенести все имена тегов без префикса в выражении в указанное пространство имён.
-
findall(match, namespaces=None) -
Находит все подходящие подэлементы по имени тега или пути. Возвращает список всех подходящих элементов в порядке документа. namespaces — необязательное сопоставление префиксов пространств имён с полными именами. Передайте
''в качестве префикса, чтобы перенести все имена тегов без префикса в выражении в указанное пространство имён.
-
findtext(match, default=None, namespaces=None) -
Находит текст первого подэлемента, соответствующего match. match может быть именем тега или путём. Возвращает текстовое содержимое первого подходящего элемента или default, если элемент не найден. Обратите внимание: если в подходящем элементе нет текстового содержимого, возвращается пустая строка. namespaces — необязательное сопоставление префиксов пространств имён с полными именами. Передайте
''в качестве префикса, чтобы перенести все имена тегов без префикса в выражении в указанное пространство имён.
-
insert(index, subelement) -
Вставляет subelement в указанную позицию этого элемента. Вызывает
TypeError, если subelement не являетсяElement.
-
iter(tag=None) -
Создаёт итератор по дереву, используя текущий элемент в качестве корня. Итератор проходит по этому элементу и всем его потомкам в порядке документа (сначала в глубину). Если tag не равен
Noneили'*', итератор возвращает только элементы, тег которых совпадает с tag. Если во время итерации структура дерева изменяется, результат не определён.Добавлено в версии 3.2.
-
iterfind(match, namespaces=None) -
Находит все подходящие подэлементы по имени тега или пути. Возвращает итерируемый объект, выдающий все подходящие элементы в порядке документа. namespaces — необязательное сопоставление префиксов пространств имён с полными именами.
Добавлено в версии 3.2.
-
itertext() -
Создаёт итератор по тексту. Итератор проходит по этому элементу и всем его подэлементам в порядке документа и возвращает весь внутренний текст.
Добавлено в версии 3.2.
-
makeelement(tag, attrib) -
Создаёт новый объект элемента того же типа, что и этот элемент. Не вызывайте этот метод; вместо него используйте фабричную функцию
SubElement().
-
remove(subelement) -
Удаляет subelement из элемента. В отличие от методов find*, этот метод сравнивает элементы по идентичности экземпляров, а не по значению тега или содержимому.
Объекты
Elementтакже поддерживают следующие методы последовательностей для работы с подэлементами:__delitem__(),__getitem__(),__setitem__(),__len__().Внимание: элементы без подэлементов при проверке истинности дают
False. В одном из будущих выпусков Python все элементы будут даватьTrueнезависимо от наличия подэлементов. Вместо этого предпочтительно использовать явные проверкиlen(elem)илиelem is not None:element = root.find('foo') if not element: # careful! print("element not found, or element has no subelements") if element is None: print("element not found")Изменено в версии 3.12: Проверка логического значения Element вызывает
DeprecationWarning.До Python 3.8 порядок сериализации XML-атрибутов элементов искусственно делали предсказуемым, сортируя атрибуты по имени. С учётом гарантированного теперь порядка словарей это произвольное переупорядочивание было удалено в Python 3.8, чтобы сохранять порядок, в котором атрибуты изначально были разобраны или созданы пользовательским кодом.
В целом пользовательскому коду не следует зависеть от определённого порядка атрибутов, поскольку набор информации XML явно не рассматривает порядок атрибутов как носитель информации. Код должен быть готов к любому порядку атрибутов на входе. Если требуется детерминированный вывод XML, например для криптографической подписи или тестовых наборов данных, доступна каноническая сериализация с помощью функции
canonicalize().Если канонический вывод неприменим, но при выводе всё же желателен определённый порядок атрибутов, следует создавать атрибуты непосредственно в нужном порядке, чтобы избежать несоответствий ожиданиям читателей кода. Если это трудно сделать, перед сериализацией можно применить следующий рецепт, чтобы задать порядок независимо от создания Element:
def reorder_attributes(root): for el in root.iter(): attrib = el.attrib if len(attrib) > 1: # adjust attribute order, e.g. by sorting attribs = sorted(attrib.items()) attrib.clear() attrib.update(attribs) -
Объекты ElementTree
-
class xml.etree.ElementTree.ElementTree(element=None, file=None) -
Класс-обёртка ElementTree. Этот класс представляет всю иерархию элементов и добавляет поддержку сериализации в стандартный XML и из него.
element — корневой элемент. Если указан file, дерево инициализируется содержимым XML-файла.
-
_setroot(element) -
Заменяет корневой элемент этого дерева. Текущее содержимое дерева удаляется и заменяется указанным элементом. Используйте с осторожностью. element — экземпляр элемента.
-
find(match, namespaces=None) -
То же, что и
Element.find(), но поиск начинается с корня дерева.
-
findall(match, namespaces=None) -
То же, что и
Element.findall(), но поиск начинается с корня дерева.
-
findtext(match, default=None, namespaces=None) -
То же, что и
Element.findtext(), но поиск начинается с корня дерева.
-
getroot() -
Возвращает корневой элемент этого дерева.
-
iter(tag=None) -
Создаёт и возвращает итератор по дереву для корневого элемента. Итератор проходит по всем элементам этого дерева в порядке разделов. tag — тег для поиска (по умолчанию возвращаются все элементы).
-
iterfind(match, namespaces=None) -
То же, что и
Element.iterfind(), но поиск начинается с корня дерева.Добавлено в версии 3.2.
-
parse(source, parser=None) -
Загружает внешний раздел XML в это дерево элементов. source — имя файла или файловый объект. parser — необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор
XMLParser. Возвращает корневой элемент раздела.
-
write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml', *, short_empty_elements=True) -
Записывает дерево элементов в файл в формате XML. file — имя файла или открытый для записи файловый объект. encoding [1] — кодировка вывода (по умолчанию US-ASCII). xml_declaration определяет, следует ли добавлять в файл объявление XML. Используйте
False, чтобы никогда его не добавлять,True— чтобы добавлять всегда,None— чтобы добавлять, только если кодировка не US-ASCII, UTF-8 или Unicode (по умолчаниюNone). default_namespace задаёт пространство имён XML по умолчанию (для «xmlns»). method — это"xml","html"или"text"(по умолчанию"xml"). Параметр только с именованным аргументом short_empty_elements управляет форматированием элементов без содержимого. Если заданоTrue(значение по умолчанию), они выводятся как одиночный тег с закрывающим слэшем; в противном случае — как пара открывающего и закрывающего тегов.Вывод представляет собой строку (
str) или двоичные данные (bytes). Это определяется аргументом encoding. Если encoding равен"unicode", вывод представляет собой строку; в противном случае — двоичные данные. Обратите внимание: это может не соответствовать типу file, если это открытый файловый объект. Не пытайтесь записать строку в двоичный поток или наоборот.Изменено в версии 3.4: Добавлен параметр short_empty_elements.
Изменено в версии 3.8: Метод
write()теперь сохраняет порядок атрибутов, заданный пользователем.
-
Это XML-файл, который будет изменён:
<html>
<head>
<title>Example page</title>
</head>
<body>
<p>Moved to <a href="http://example.org/">example.org</a>
or <a href="http://example.com/">example.com</a>.</p>
</body>
</html>
Пример изменения атрибута «target» у каждой ссылки в первом абзаце:
>>> from xml.etree.ElementTree import ElementTree
>>> tree = ElementTree()
>>> tree.parse("index.xhtml")
<Element 'html' at 0xb77e6fac>
>>> p = tree.find("body/p") # Finds first occurrence of tag p in body
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a")) # Returns list of all links
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in links: # Iterates through all found links
... i.attrib["target"] = "blank"
...
>>> tree.write("output.xhtml")
Объекты QName
-
class xml.etree.ElementTree.QName(text_or_uri, tag=None) -
Обёртка QName. Её можно использовать для обёртывания значения атрибута QName, чтобы обеспечить корректную обработку пространств имён при выводе. text_or_uri — строка со значением QName в формате {uri}local или, если задан аргумент tag, часть URI значения QName. Если задан tag, первый аргумент интерпретируется как URI, а этот аргумент — как локальное имя. Экземпляры
QNameявляются непрозрачными.
Объекты TreeBuilder
-
class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False) -
Универсальный построитель структуры элементов. Этот построитель преобразует последовательность вызовов методов start, data, end, comment и pi в корректную структуру элементов. Этот класс можно использовать для построения структуры элементов с помощью пользовательского анализатора XML или анализатора другого формата, подобного XML.
Если задан element_factory, он должен быть вызываемым объектом, принимающим два позиционных аргумента: тег и словарь атрибутов. Ожидается, что он вернёт новый экземпляр элемента.
Если заданы функции comment_factory и pi_factory, они должны работать подобно функциям
Comment()иProcessingInstruction(), создавая комментарии и инструкции обработки. Если функции не заданы, используются фабрики по умолчанию. Если insert_comments и/или insert_pis имеют значение true, комментарии/инструкции обработки вставляются в дерево, если они находятся внутри корневого элемента (но не за его пределами).-
close() -
Сбрасывает буферы построителя и возвращает корневой элемент документа верхнего уровня. Возвращает экземпляр
Element.
-
data(data) -
Добавляет текст к текущему элементу. data — строка. Это должна быть либо байтовая строка, либо строка Unicode.
-
end(tag) -
Закрывает текущий элемент. tag — имя элемента. Возвращает закрытый элемент.
-
start(tag, attrs) -
Открывает новый элемент. tag — имя элемента. attrs — словарь с атрибутами элемента. Возвращает открытый элемент.
-
comment(text) -
Создаёт комментарий с указанным текстом text. Если
insert_commentsимеет значение true, комментарий также будет добавлен в дерево.Добавлено в версии 3.8.
-
pi(target, text) -
Создаёт инструкцию обработки с указанными именем target и текстом text. Если
insert_pisимеет значение true, инструкция также будет добавлена в дерево.Добавлено в версии 3.8.
Кроме того, пользовательский объект
TreeBuilderможет предоставлять следующие методы:-
doctype(name, pubid, system) -
Обрабатывает объявление doctype. name — имя doctype. pubid — публичный идентификатор. system — системный идентификатор. Этот метод отсутствует в классе
TreeBuilderпо умолчанию.Добавлено в версии 3.2.
-
start_ns(prefix, uri) -
Вызывается каждый раз, когда анализатор встречает новое объявление пространства имён, перед обратным вызовом
start()для открывающего элемента, в котором оно задано. prefix равен''для пространства имён по умолчанию и имени объявленного префикса пространства имён в остальных случаях. uri — URI пространства имён.Добавлено в версии 3.8.
-
end_ns(prefix) -
Вызывается после обратного вызова
end()элемента, объявившего сопоставление префикса пространства имён, и получает имя префикса prefix, область действия которого завершилась.Добавлено в версии 3.8.
-
-
class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None) -
Средство записи C14N 2.0. Аргументы те же, что и у функции
canonicalize(). Этот класс не строит дерево, а преобразует события обратных вызовов непосредственно в сериализованное представление с помощью функции write.Добавлено в версии 3.8.
Объекты XMLParser
-
class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None) -
Этот класс является низкоуровневым строительным блоком модуля. Он использует
xml.parsers.expatдля эффективного событийного разбора XML. Ему можно передавать XML-данные по частям с помощью методаfeed(), а события разбора преобразуются в push API — вызовом обратных вызовов объекта target. Если target не указан, используется стандартныйTreeBuilder. Если задан encoding [1], это значение переопределяет кодировку, указанную в XML-файле.Изменено в версии 3.8: Теперь параметры являются именованными. Аргумент html больше не поддерживается.
-
close() -
Завершает передачу данных парсеру. Возвращает результат вызова метода
close()объекта target, переданного при создании; по умолчанию это корневой элемент документа.
-
feed(data) -
Передаёт данные парсеру. data — это закодированные данные.
-
flush() -
Запускает разбор ранее переданных, но ещё не разобранных данных, что позволяет получать обратную связь быстрее, особенно при использовании Expat >=2.6.0. Реализация
flush()временно отключает отложенный повторный разбор в Expat (если он включён) и запускает повторный разбор. Отключение отложенного повторного разбора имеет последствия для безопасности; подробности см. вxml.parsers.expat.xmlparser.SetReparseDeferralEnabled().Обратите внимание, что
flush()было перенесено в некоторые более ранние выпуски CPython в качестве исправления безопасности. Если код используется в разных версиях Python, проверьте наличиеflush()с помощьюhasattr().Добавлено в версии 3.13.
XMLParser.feed()вызывает методstart(tag, attrs_dict)объекта target для каждого открывающего тега, его методend(tag)— для каждого закрывающего тега, а данные обрабатываются методомdata(data). О других поддерживаемых методах обратного вызова см. в описании классаTreeBuilder.XMLParser.close()вызывает методclose()объекта target.XMLParserможно использовать не только для построения древовидной структуры. В этом примере определяется максимальная глубина XML-файла:>>> from xml.etree.ElementTree import XMLParser >>> class MaxDepth: # The target object of the parser ... maxDepth = 0 ... depth = 0 ... def start(self, tag, attrib): # Called for each opening tag. ... self.depth += 1 ... if self.depth > self.maxDepth: ... self.maxDepth = self.depth ... def end(self, tag): # Called for each closing tag. ... self.depth -= 1 ... def data(self, data): ... pass # We do not need to do anything with data. ... def close(self): # Called when all data has been parsed. ... return self.maxDepth ... >>> target = MaxDepth() >>> parser = XMLParser(target=target) >>> exampleXml = """ ... <a> ... <b> ... </b> ... <b> ... <c> ... <d> ... </d> ... </c> ... </b> ... </a>""" >>> parser.feed(exampleXml) >>> parser.close() 4
-
Объекты XMLPullParser
-
class xml.etree.ElementTree.XMLPullParser(events=None) -
Потоковый парсер, подходящий для неблокирующих приложений. Его API для ввода похож на API
XMLParser, но вместо передачи вызовов целевому объекту обратного вызоваXMLPullParserсобирает внутренний список событий разбора и позволяет пользователю считывать их. events — это последовательность событий, которые нужно возвращать. Поддерживаемые события — строки"start","end","comment","pi","start-ns"и"end-ns"(события «ns» используются для получения подробной информации о пространствах имён). Если events не указан, возвращаются только события"end".-
feed(data) -
Передаёт парсеру указанные байтовые данные.
-
flush() -
Запускает разбор ранее переданных, но ещё не разобранных данных, что позволяет получать обратную связь быстрее, особенно при использовании Expat >=2.6.0. Реализация
flush()временно отключает отложенный повторный разбор в Expat (если он включён) и запускает повторный разбор. Отключение отложенного повторного разбора имеет последствия для безопасности; подробности см. вxml.parsers.expat.xmlparser.SetReparseDeferralEnabled().Обратите внимание, что
flush()было перенесено в некоторые более ранние выпуски CPython в качестве исправления безопасности. Если код используется в разных версиях Python, проверьте наличиеflush()с помощьюhasattr().Добавлено в версии 3.13.
-
close() -
Сообщает парсеру о завершении потока данных. В отличие от
XMLParser.close(), этот метод всегда возвращаетNone. События, которые ещё не были получены к моменту закрытия парсера, всё ещё можно прочитать с помощьюread_events().
-
read_events() -
Возвращает итератор по событиям, обнаруженным в данных, переданных парсеру. Итератор возвращает пары
(event, elem), где event — строка, обозначающая тип события (например,"end"), а elem — обнаруженный объектElementили другое контекстное значение, как указано ниже.-
start,end: текущий элемент. -
comment,pi: текущий комментарий / инструкция обработки -
start-ns: кортеж(prefix, uri), содержащий объявленное сопоставление пространств имён. -
end-ns:None(в будущей версии это может измениться)
События, предоставленные при предыдущем вызове
read_events(), повторно возвращаться не будут. События извлекаются из внутренней очереди только при получении из итератора, поэтому параллельная итерация нескольких читателей по итераторам, полученным с помощьюread_events(), приведёт к непредсказуемым результатам. -
Примечание
XMLPullParserгарантирует только то, что при выдаче события «start» он уже обработал символ «>» открывающего тега, поэтому атрибуты определены, но содержимое атрибутов text и tail на этом этапе не определено. То же относится к дочерним элементам; они могут присутствовать, а могут и отсутствовать.Если вам нужен полностью заполненный элемент, используйте события «end».
Добавлено в версии 3.4.
Изменено в версии 3.8: Добавлены события
commentиpi. -
Исключения
-
class xml.etree.ElementTree.ParseError -
Ошибка разбора XML, возникающая при сбое разбора в различных методах этого модуля. Строковое представление экземпляра этого исключения содержит понятное пользователю сообщение об ошибке. Кроме того, доступны следующие атрибуты:
-
code -
Числовой код ошибки парсера expat. Список кодов ошибок и их значений см. в документации
xml.parsers.expat.
-
position -
Кортеж с номерами line и column, указывающими место возникновения ошибки.
-
Сноски
© 2001 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/xml.etree.elementtree.html