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