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 вытягивания для неблокирующего парсинга
Большинство функций парсинга, предоставляемых этим модулем, требуют, чтобы весь документ был прочитан сразу, прежде чем возвращать любой результат. Можно использовать XMLParser и поставлять данные в него по частям, но это API «толчок», который вызывает методы целевого обратного вызова, что слишком низкий уровень и неудобно для большинства задач. Иногда пользователю нужно возможность парсить XML по частям без блокировок, при этом пользуясь удобством полностью построенных Element объектов.
Самым мощным инструментом для этого является XMLPullParser. Он не требует блокирующего чтения для получения данных XML и вместо этого поставляет данные по частям с помощью вызовов XMLPullParser.feed(). Для получения проанализированных элементов XML вызовите XMLPullParser.read_events(). Вот пример:
>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
... print(event)
... print(elem.tag, 'text=', elem.text)
...
end
Очевидный случай использования — приложения, работающие в асинхронном режиме, где XML-данные поступают из сокета или считываются по частям с какого-либо устройства хранения. В таких случаях блокирующие чтения неприемлемы.
Поскольку он очень гибкий, XMLPullParser может быть неудобным для использования в простых случаях. Если вас не смущает, что ваше приложение будет блокироваться при чтении XML-данных, но вы все равно хотите иметь возможности по частям, взгляните на iterparse(). Он может быть полезен, когда вы читаете большой XML-документ и не хотите хранить его полностью в памяти.
Поиск интересных элементов
Element имеет некоторые полезные методы, которые помогают рекурсивно итерировать по всему поддереву ниже него (по его дочерним элементам, их дочерним элементам и т. д.). Например, Element.iter():
>>> for neighbor in root.iter('neighbor'):
... print(neighbor.attrib)
...
{'name': 'Austria', 'direction': 'E'}
{'name': 'Switzerland', 'direction': 'W'}
{'name': 'Malaysia', 'direction': 'N'}
{'name': 'Costa Rica', 'direction': 'W'}
{'name': 'Colombia', 'direction': 'E'}
Element.findall() находит только элементы с тегом, которые являются прямыми дочерними элементами текущего элемента. Element.find() находит первый дочерний элемент с определенным тегом, а Element.text получает текстовое содержимое элемента. Element.get() получает атрибуты элемента:
>>> for country in root.findall('country'):
... rank = country.find('rank').text
... name = country.get('name')
... print(name, rank)
...
Liechtenstein 1
Singapore 4
Panama 68
Более сложные условия выбора элементов возможны с помощью XPath.
Изменение XML-файла
ElementTree предоставляет простой способ построения XML-документов и записи их в файлы. Метод ElementTree.write() служит для этой цели.
После создания объект Element можно изменить, непосредственно изменив его поля (например, Element.text), добавив и изменив атрибуты (метод Element.set()), а также добавив новые дочерние элементы (например, с помощью Element.append()).
Предположим, что мы хотим прибавить единицу к рейтингу каждой страны и добавить атрибут updated к элементу рейтинга:
>>> for rank in root.iter('rank'):
... new_rank = int(rank.text) + 1
... rank.text = str(new_rank)
... rank.set('updated', 'yes')
...
>>> tree.write('output.xml')
Наш XML теперь выглядит так:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
Мы можем удалить элементы с помощью Element.remove(). Предположим, что мы хотим удалить все страны с рейтингом выше 50:
>>> for country in root.findall('country'):
... # using root.findall() to avoid removal during traversal
... rank = int(country.find('rank').text)
... if rank > 50:
... root.remove(country)
...
>>> tree.write('output.xml')
Обратите внимание, что одновременное изменение во время итерации может привести к проблемам, как и при итерации и изменении списков или словарей Python. Поэтому в примере сначала собираются все соответствующие элементы с root.findall(), а затем уже происходит итерация по списку совпадений.
Наш XML теперь выглядит так:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
</data>
Создание XML-документов
Функция SubElement() также обеспечивает удобный способ создания новых дочерних элементов для заданного элемента:
>>> a = ET.Element('a')
>>> b = ET.SubElement(a, 'b')
>>> c = ET.SubElement(a, 'c')
>>> d = ET.SubElement(c, 'd')
>>> ET.dump(a)
<a><b /><c><d /></c></a>
Парсинг XML с именованными пространствами имён
Если входной XML-документ содержит пространства имен, теги и атрибуты с префиксами в форме prefix:sometag расширяются до {uri}sometag где префикс заменяется полным 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.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_aware_attrs: набор имён атрибутов с поддержкой полных имён, в которых префиксы
-
должны быть заменены в текстовом содержимом (по умолчанию: пусто)
- exclude_attrs: набор имён атрибутов, которые не должны быть сериализованы
- exclude_tags: набор имён тегов, которые не должны быть сериализованы
В списке параметров выше «набор» относится к любому набору или итерируемому объекту строк, порядок не ожидается.
Новая в версии 3.8.
-
xml.etree.ElementTree.Comment(text=None) -
Фабрика элементов комментариев. Эта фабричная функция создаёт специальный элемент, который стандартный сериализатор будет сериализовать как XML-комментарий. Строка комментария может быть либо строкой байтов, либо строкой Unicode. text — это строка, содержащая строку комментария. Возвращает экземпляр элемента, представляющий комментарий.
Обратите внимание, что
XMLParserпропускает комментарии во входных данных вместо создания для них объектов комментариев.ElementTreeбудет содержать узлы комментариев только в том случае, если они были вставлены в дерево с помощью одного из методовElement.
-
xml.etree.ElementTree.dump(elem) -
Записывает дерево элементов или структуру элементов в sys.stdout. Эту функцию следует использовать только для отладки.
Точный формат вывода зависит от реализации. В этой версии он записывается как обычный XML-файл.
elem — это дерево элементов или отдельный элемент.
Изменено в версии 3.8: Функция
dump()теперь сохраняет порядок атрибутов, указанный пользователем.
-
xml.etree.ElementTree.fromstring(text, parser=None) -
Парсит XML-раздел из строковой константы. Аналогично
XML(). text — это строка, содержащая XML-данные. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсерXMLParser. Возвращает экземплярElement.
-
xml.etree.ElementTree.fromstringlist(sequence, parser=None) -
Парсит XML-документ по последовательности фрагментов строк. sequence — список или другая последовательность, содержащая фрагменты XML-данных. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер
XMLParser. Возвращает экземплярElement.Новая в версии 3.2.
-
xml.etree.ElementTree.indent(tree, space=' ', level=0) -
Добавляет пробелы к поддереву, чтобы визуально отступать дерево. Это можно использовать для генерации красивого отформатированного XML-вывода. tree может быть элементом или деревом элементов. space — это строка пробелов, которая будет вставляться для каждого уровня отступа, по умолчанию это две пробельные символа. Для отступа частичных поддеревьев внутри уже отступающего дерева передайте начальный уровень отступа как level.
Новая в версии 3.9.
-
xml.etree.ElementTree.iselement(element) -
Проверяет, является ли объект допустимым объектом элемента. element — экземпляр элемента. Возвращает
Trueесли это объект элемента.
-
xml.etree.ElementTree.iterparse(source, events=None, parser=None) -
Постепенно парсит XML-раздел в дерево элементов и сообщает пользователю, что происходит. source — имя файла или объект файла, содержащий XML-данные. events — последовательность событий, которые нужно сообщить обратно. Поддерживаемые события — строки
"start","end","comment","pi","start-ns"и"end-ns"(события «ns» используются для получения подробной информации о пространствах имён). Если events опущено, сообщаются только события"end". parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсерXMLParser. parser должен быть подклассомXMLParserи может использовать только целевой объект по умолчаниюTreeBuilder. Возвращает итератор, предоставляющий пары(event, elem).Обратите внимание, что хотя
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) -
Фабрика элементов PI. Эта фабричная функция создаёт специальный элемент, который будет сериализован как XML-обрабатывающая инструкция. target — это строка, содержащая цель PI. text — это строка, содержащая содержимое PI, если оно задано. Возвращает экземпляр элемента, представляющий обрабатывающую инструкцию.
Обратите внимание, что
XMLParserпропускает обрабатывающие инструкции во входных данных вместо создания для них объектов комментариев.ElementTreeбудет содержать узлы обработки инструкций только в том случае, если они были вставлены в дерево с помощью одного из методовElement.
-
xml.etree.ElementTree.register_namespace(prefix, uri) -
Регистрирует префикс пространства имён. Регистр глобальный, и любая существующая сопоставление для заданного префикса или URI пространства имён будет удалено. prefix — префикс пространства имён. uri — URI пространства имён. Теги и атрибуты в этом пространстве имён будут сериализованы с данным префиксом, если это возможно.
Новая в версии 3.2.
-
xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra) -
Функция-фабрика для создания дочерних элементов. Она создаёт экземпляр элемента и добавляет его к существующему элементу.
Имя элемента, имена атрибутов и значения атрибутов могут быть строками байтов или строками Юникода. parent — родительский элемент. tag — имя дочернего элемента. attrib — необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные в качестве ключевых аргументов. Возвращает экземпляр элемента.
-
xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True) -
Генерирует строковое представление XML-элемента, включая все дочерние элементы. element — экземпляр
Element. encoding 1 — кодировка вывода (по умолчанию US-ASCII). Используйтеencoding="unicode"для генерации строки Юникода (в противном случае генерируется строка байтов). method может быть"xml","html"или"text"(по умолчанию"xml"). xml_declaration, default_namespace и short_empty_elements имеют такое же значение, как и вElementTree.write(). Возвращает (опционально) закодированную строку, содержащую XML-данные.В версии 3.4: Параметр short_empty_elements.
В версии 3.8: Параметры xml_declaration и default_namespace.
В версии 3.8: Функция
tostring()теперь сохраняет порядок атрибутов, указанный пользователем.
-
xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True) -
Генерирует строковое представление XML-элемента, включая все дочерние элементы. element — экземпляр
Element. encoding 1 — кодировка вывода (по умолчанию US-ASCII). Используйтеencoding="unicode"для генерации строки Юникода (в противном случае генерируется строка байтов). method может быть"xml","html"или"text"(по умолчанию"xml"). xml_declaration, default_namespace и short_empty_elements имеют такое же значение, как и вElementTree.write(). Возвращает список (опционально) закодированных строк, содержащих XML-данные. Он не гарантирует какой-либо определённой последовательности, за исключениемb"".join(tostringlist(element)) == tostring(element).В версии 3.2.
В версии 3.4: Параметр short_empty_elements.
В версии 3.8: Параметры xml_declaration и default_namespace.
В версии 3.8: Функция
tostringlist()теперь сохраняет порядок атрибутов, указанный пользователем.
-
xml.etree.ElementTree.XML(text, parser=None) -
Парсит XML-раздел из строковой константы. Эта функция может использоваться для вставки «XML-литералов» в код Python. text — строка, содержащая XML-данные. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер
XMLParser. Возвращает экземплярElement.
-
xml.etree.ElementTree.XMLID(text, parser=None) -
Парсит XML-раздел из строковой константы и также возвращает словарь, сопоставляющий идентификаторы элементов с элементами. 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 установлены в true, комментарии/инструкции обработки будут вставлены в дерево, если они встречаются внутри корневого элемента (но не вне его).-
close() -
Очищает буферы генератора и возвращает корневой элемент документа. Возвращает экземпляр
Element.
-
data(data) -
Добавляет текст к текущему элементу. data — строка. Это может быть строка байтов или строка Юникода.
-
end(tag) -
Закрывает текущий элемент. tag — имя элемента. Возвращает закрытый элемент.
-
start(tag, attrs) -
Открывает новый элемент. tag — имя элемента. attrs — словарь, содержащий атрибуты элемента. Возвращает открытый элемент.
-
comment(text) -
Создаёт комментарий с заданным текстом text. Если
insert_commentsравно true, он также добавит его в дерево.Добавлена в версии 3.8.
-
pi(target, text) -
Создаёт инструкцию обработки с заданным именем target и текстом text. Если
insert_pisравно true, он также добавит её в дерево.Добавлена в версии 3.8.
Кроме того, пользовательский объект
TreeBuilderможет предоставить следующие методы:-
doctype(name, pubid, system) -
Обрабатывает объявление типа документа. name — имя типа документа. pubid — публичный идентификатор. system — системный идентификатор. Этот метод отсутствует в стандартном классе
TreeBuilder.Добавлена в версии 3.2.
-
start_ns(prefix, uri) -
Вызывается всякий раз, когда парсер находит новое объявление пространства имён, перед вызовом
start()для открывающего элемента, который его определяет. prefix —''для пространства имён по умолчанию и имя префикса объявленного пространства имён в противном случае. uri — URI пространства имён.Добавлена в версии 3.8.
-
end_ns(prefix) -
Вызывается после вызова
end()элемента, который объявил сопоставление префикса пространства имён, с именем префикса prefix, вышедшего из области видимости.Добавлена в версии 3.8.
-
-
class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None) -
Писатель C14N 2.0. Аргументы такие же, как и для функции
canonicalize(). Этот класс не строит дерево, а напрямую преобразует события обратного вызова в сериализованную форму с помощью функции write.Добавлена в версии 3.8.
Объекты XMLParser
-
class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None) -
Этот класс является низкоуровневым строительным блоком модуля. Он использует
xml.parsers.expatдля эффективного, основанного на событиях, парсинга XML. Его можно поочерёдно подключать к данным XML с помощью методаfeed(), а события парсинга преобразуются в API "push" — путём вызова обратных вызовов на объекте target. Если target опущен, используется стандартныйTreeBuilder. Если задано encoding 1, это значение переопределяет кодировку, указанную в файле XML.Изменено в версии 3.8: Параметры теперь только ключевые. Аргумент html больше не поддерживается.
-
close() -
Завершает подачу данных в парсер. Возвращает результат вызова метода
close()объекта target, переданного во время создания; по умолчанию это корневой элемент документа.
-
feed(data) -
Подает данные в парсер. data — закодированные данные.
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 со стороны ввода похож на
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–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/xml.etree.elementtree.html