Содержание страницы
xml.etree.ElementTree – API ElementTree для XML¶xml.etree.ElementTree – The ElementTree XML API
Исходный код: Lib/xml/etree/ElementTree.py
Модуль xml.etree.ElementTree реализует простой и эффективный API
для разбора и создания XML-данных.
Изменено в версии 3.3: Этот модуль использует быструю реализацию, если она доступна.
Устарело с версии 3.3: Модуль xml.etree.cElementTree устарел.
Примечание
Если требуется разобрать непроверенные или неаутентифицированные данные, см. Безопасность XML.
Учебное руководство¶Tutorial
Это краткое руководство по использованию xml.etree.ElementTree (ET в
краткой форме). Цель – продемонстрировать некоторые основные компоненты и базовые
концепции модуля.
XML-дерево и элементы¶XML tree and elements
XML – это изначально иерархический формат данных, и наиболее естественный способ его представления – дерево. ET содержит два класса для этой цели:
ElementTree представляет весь XML-документ как дерево, а
Element представляет отдельный узел в этом дереве. Взаимодействие со всем документом (чтение и запись в файлы/из файлов) обычно выполняется
на уровне ElementTree. Взаимодействие с отдельным элементом XML
и его дочерними элементами выполняется на уровне Element.
Разбор XML¶Parsing XML
В качестве примера для этого раздела мы будем использовать вымышленный XML-документ country_data.xml:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank>1</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank>4</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank>68</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
Данные можно импортировать, прочитав файл:
import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()
Или непосредственно из строки:
root = ET.fromstring(country_data_as_string)
fromstring() разбирает XML из строки непосредственно в Element,
который является корневым элементом разобранного дерева. Другие функции разбора могут
создавать ElementTree. Для уточнения обратитесь к документации.
Как Element, root имеет тег и словарь атрибутов:
>>> root.tag
'data'
>>> root.attrib
{}
У него также есть дочерние узлы, которые можно перебирать:
>>> for child in root:
... print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}
Дочерние узлы вложены, и к конкретным дочерним узлам можно обратиться по индексу:
>>> root[0][1].text
'2008'
Примечание
Не все элементы XML-входных данных станут элементами разобранного дерева.
В настоящее время этот модуль пропускает любые XML-комментарии,
инструкции по обработке и объявления типа документа во входных данных.
Тем не менее, деревья, построенные с помощью API этого модуля, а не путём разбора XML-текста, могут содержать комментарии и инструкции по обработке;
они будут включены при генерации XML-вывода.
Доступ к объявлению типа документа можно получить, передав пользовательский экземпляр TreeBuilder конструктору XMLParser.
Pull API для неблокирующего разбора¶Pull API for non-blocking parsing
Большинство функций разбора, предоставляемых этим модулем, требуют, чтобы весь документ
был прочитан сразу перед возвратом какого-либо результата. Можно использовать
XMLParser и передавать в него данные постепенно, но это push API, который
вызывает методы на целевом колбэке, что является слишком низкоуровневым и неудобным для
большинства задач. Иногда пользователю действительно нужно иметь возможность разбирать XML
постепенно, без блокирующих операций, пользуясь удобством полностью построенных
объектов Element.
Самый мощный инструмент для этого – XMLPullParser. Он не требует блокирующего чтения для получения XML-данных, а вместо этого получает данные
постепенно с помощью вызовов XMLPullParser.feed(). Чтобы получить разобранные XML-элементы, вызовите XMLPullParser.read_events(). Вот пример:
>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
... print(event)
... print(elem.tag, 'text=', elem.text)
...
end
mytag text= sometext more text
Очевидный вариант использования – приложения, работающие в неблокирующем режиме, где XML-данные поступают из сокета или читаются постепенно с какого-либо устройства хранения. В таких случаях блокирующие чтения неприемлемы.
Из-за своей гибкости XMLPullParser может быть неудобен для
более простых задач. Если вы не против того, чтобы ваше приложение блокировалось при чтении XML-данных, но всё же хотите иметь возможность инкрементального разбора, обратите внимание
на iterparse(). Он может быть полезен при чтении большого XML-документа,
который вы не хотите полностью хранить в памяти.
Там, где требуется немедленная обратная связь через события, вызов метода
XMLPullParser.flush() может помочь уменьшить задержку;
пожалуйста, обязательно изучите соответствующие замечания по безопасности.
Поиск интересующих элементов¶Finding interesting elements
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-файла¶Modifying an XML File
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'):
... # использование root.findall() для предотвращения удаления во время обхода
... 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-документов¶Building XML documents
Функция 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 с пространствами имён¶Parsing XML with Namespaces
Если во входном 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 support
Этот модуль предоставляет ограниченную поддержку XPath-выражений для поиска элементов в дереве. Цель – поддержать небольшое подмножество сокращённого синтаксиса; полноценный движок XPath выходит за рамки модуля.
Пример¶Example
Вот пример, демонстрирующий некоторые возможности XPath этого
модуля. Будем использовать XML-документ countrydata из раздела
Разбор XML:
import xml.etree.ElementTree as ET
root = ET.fromstring(countrydata)
# Элементы верхнего уровня
root.findall(".")
# Все элементы 'neighbor', являющиеся внуками дочерних элементов 'country' верхнего уровня
# элементы
root.findall("./country/neighbor")
# Узлы с name='Singapore', имеющие дочерний элемент 'year'
root.findall(".//year/..[@name='Singapore']")
# Элементы 'year', являющиеся дочерними для узлов с name='Singapore'
root.findall(".//*[@name='Singapore']/year")
# Все элементы 'neighbor', являющиеся вторым дочерним элементом своего родителя
root.findall(".//neighbor[2]")
Для XML с пространствами имён используйте обычную нотацию с {namespace}tag:
# Все теги dublin-core "title" в документе
root.findall(".//{http://purl.org/dc/elements/1.1/}title")
Поддерживаемый синтаксис XPath¶Supported XPath syntax
Синтаксис |
Значение |
|---|---|
|
Выбирает все дочерние элементы с заданным тегом.
Например, Изменено в версии 3.8: Добавлена поддержка подстановочных символов в виде звёздочки. |
|
Выбирает все дочерние элементы, включая комментарии и
инструкции обработки. Например, |
|
Выбирает текущий узел. Это особенно полезно в начале пути, чтобы указать, что это относительный путь. |
|
Выбирает все вложенные элементы на всех уровнях ниже
текущего элемента. Например, |
|
Выбирает родительский элемент. Возвращает |
|
Выбирает все элементы, у которых есть указанный атрибут. |
|
Выбирает все элементы, у которых указанный атрибут имеет заданное значение. Значение не может содержать кавычки. |
|
Выбирает все элементы, у которых указанный атрибут не равен заданному значению. Значение не может содержать кавычки. Добавлено в версии 3.10. |
|
Выбирает все элементы, у которых есть дочерний элемент с именем
|
|
Выбирает все элементы, полное текстовое содержимое которых,
включая потомков, равно заданному Добавлено в версии 3.7. |
|
Выбирает все элементы, полное текстовое содержимое которых,
включая потомков, не равно заданному
Добавлено в версии 3.10. |
|
Выбирает все элементы, у которых есть дочерний элемент с именем
|
|
Выбирает все элементы, у которых есть дочерний элемент с именем
Добавлено в версии 3.10. |
|
Выбирает все элементы, расположенные на указанной
позиции. Позиция может быть целым числом
(1 – первая позиция), выражением |
Предикаты (выражения в квадратных скобках) должны предваряться именем тега, звёздочкой или другим предикатом. Предикаты position должны предваряться именем тега.
Ссылка¶Reference
Функции¶Functions
- xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)¶
Функция преобразования C14N 2.0.
Канонизация – это способ нормализации вывода XML, который позволяет сравнивать побайтово и создавать цифровые подписи. Она уменьшает свободу, которую имеют сериализаторы XML, и вместо этого генерирует более ограниченное представление XML. Основные ограничения касаются размещения объявлений пространств имён, порядка атрибутов и игнорируемых пробельных символов.
Эта функция принимает на вход строку XML-данных (xml_data) или путь к файлу или файлоподобный объект (from_file), преобразует их в каноническую форму и записывает результат с помощью файлоподобного объекта out, если он указан, или возвращает его в виде текстовой строки, если не указан. Выходной файл получает текст, а не байты. Поэтому он должен быть открыт в текстовом режиме с кодировкой
utf-8.Типичное использование:
xml_data = "<root>...</root>" print(canonicalize(xml_data)) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(xml_data, out=out_file) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(from_file="inputfile.xml", out=out_file)
Параметры конфигурации options следующие:
with_comments: установите true, чтобы включить комментарии (по умолчанию: false)
- strip_text: установите true, чтобы удалять пробелы до и после текстового содержимого
(по умолчанию: false)
- rewrite_prefixes: установите true, чтобы заменять префиксы пространств имён на “n{number}”
(по умолчанию: false)
- qname_aware_tags: набор имен тегов, учитывающих qname, в которых префиксы
должны заменяться в текстовом содержимом (по умолчанию: пусто)
- qname_aware_attrs: набор имен атрибутов, учитывающих qname, в которых префиксы
должны заменяться в текстовом содержимом (по умолчанию: пусто)
exclude_attrs: набор имен атрибутов, которые не должны сериализоваться
exclude_tags: набор имен тегов, которые не должны сериализоваться
В приведённом выше списке параметров под «набором» понимается любая коллекция или итерабельный объект из строк, порядок не важен.
Добавлено в версии 3.8.
- xml.etree.ElementTree.Comment(text=None)¶
Фабрика элементов Comment. Эта фабричная функция создаёт специальный элемент, который будет сериализован как 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 может быть элементом Element или ElementTree. space – строка пробелов, которая будет вставлена для каждого уровня отступа, по умолчанию два пробела. Для отступа частичных поддеревьев внутри уже отформатированного дерева передайте начальный уровень отступа как level.
Добавлено в версии 3.9.
- xml.etree.ElementTree.iselement(element)¶
Проверяет, является ли объект допустимым элементом. element – это экземпляр элемента. Возвращает
True, если это объект элемента.
- xml.etree.ElementTree.iterparse(source, events=None, parser=None)¶
Разбирает XML-раздел в дерево элементов инкрементально и сообщает пользователю о происходящем. source – это имя файла или файловый объект, содержащий XML-данные. events – последовательность событий для отчёта. Поддерживаемые события – строки
"start","end","comment","pi","start-ns"и"end-ns"(события «ns» используются для получения подробной информации о пространствах имён). Если events опущен, сообщаются только события"end". parser – необязательный экземпляр анализатора. Если не указан, используется стандартный анализаторXMLParser. parser должен быть подклассомXMLParserи может использовать только цель по умолчаниюTreeBuilder. Возвращает итератор, предоставляющий пары(event, elem); у него есть атрибутroot, который ссылается на корневой элемент результирующего XML-дерева после полного чтения source. Итератор имеет методclose(), который закрывает внутренний файловый объект, если source является именем файла.Обратите внимание, что
iterparse()строит дерево инкрементально, но выполняет блокирующие чтения из source (или указанного файла). Поэтому он не подходит для приложений, где блокирующие чтения недопустимы. Для полностью неблокирующего разбора см.XMLPullParser.Примечание
iterparse()гарантирует только, что увидел символ «>» начального тега, когда генерирует событие «start», поэтому атрибуты определены, но содержимое атрибутов text и tail на этот момент не определено. То же самое относится к дочерним элементам; они могут присутствовать или нет.Если нужен полностью заполненный элемент, используйте события "end".
Устарело с версии 3.4: Аргумент parser.
Изменено в версии 3.8: Были добавлены события
commentиpi.Изменено в версии 3.13: Добавлен метод
close().Изменено в версии 3.15: Теперь
ResourceWarningгенерируется, если итератор открыл файл и не был явно закрыт.
- xml.etree.ElementTree.parse(source, parser=None)¶
Разбирает XML-раздел в дерево элементов. source – это имя файла или файловый объект, содержащий XML-данные. parser – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор
XMLParser. Возвращает экземплярElementTree.
- xml.etree.ElementTree.ProcessingInstruction(target, text=None)¶
Фабрика PI-элементов. Эта фабричная функция создаёт специальный элемент, который будет сериализован как инструкция обработки XML. target – строка, содержащая цель PI. text – строка, содержащая содержимое PI, если задано. Возвращает экземпляр элемента, представляющий инструкцию обработки.
Обратите внимание, что
XMLParserпропускает инструкции обработки во входных данных вместо создания для них PI-объектов.ElementTreeбудет содержать узлы инструкций обработки, только если они были вставлены в дерево с помощью одного из методовElement.
- xml.etree.ElementTree.register_namespace(prefix, uri)¶
Регистрирует префикс пространства имён. Реестр является глобальным, и любое существующее сопоставление для данного префикса или URI пространства имён будет удалено. prefix – префикс пространства имён. uri – URI пространства имён. Теги и атрибуты в этом пространстве имён будут сериализованы с указанным префиксом, если это возможно.
Добавлено в версии 3.2.
- xml.etree.ElementTree.SubElement(parent, tag, /, attrib={}, **extra)¶
Фабрика подэлементов. Эта функция создаёт экземпляр элемента и добавляет его к существующему элементу.
Имя элемента, имена атрибутов и значения атрибутов могут быть как байтовыми строками, так и строками Unicode. parent – родительский элемент. tag – имя подэлемента. attrib – необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные как именованные аргументы. Возвращает экземпляр элемента.
Изменено в версии 3.15: attrib теперь может быть
frozendict.Изменено в версии 3.15: parent и tag теперь являются только позиционными параметрами.
- xml.etree.ElementTree.tostring(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)¶
Создаёт строковое представление XML-элемента, включая все подэлементы. element – это экземпляр
Element. encoding [1] – выходная кодировка (по умолчанию US-ASCII). Используйтеencoding="unicode"для создания строки Unicode (в противном случае создаётся байтовая строка). method – это либо"xml","html"или"text"(по умолчанию"xml"). xml_declaration, default_namespace и short_empty_elements имеют тот же смысл, что и вElementTree.write(). Возвращает (опционально) закодированную строку, содержащую XML-данные.Изменено в версии 3.4: Добавлен параметр short_empty_elements.
Изменено в версии 3.8: Добавлены параметры xml_declaration и default_namespace.
Изменено в версии 3.8: Функция
tostring()теперь сохраняет порядок атрибутов, заданный пользователем.
- xml.etree.ElementTree.tostringlist(element, encoding='us-ascii', method='xml', *, xml_declaration=None, default_namespace=None, short_empty_elements=True)¶
Создаёт строковое представление XML-элемента, включая все подэлементы. element – это экземпляр
Element. encoding [1] – выходная кодировка (по умолчанию US-ASCII). Используйтеencoding="unicode"для создания строки Unicode (в противном случае создаётся байтовая строка). method – это либо"xml","html"или"text"(по умолчанию"xml"). xml_declaration, default_namespace и short_empty_elements имеют тот же смысл, что и вElementTree.write(). Возвращает список (опционально) закодированных строк, содержащих XML-данные. Не гарантируется никакой конкретный порядок, за исключением того, чтоb"".join(tostringlist(element)) == tostring(element).Добавлено в версии 3.2.
Изменено в версии 3.4: Добавлен параметр short_empty_elements.
Изменено в версии 3.8: Добавлены параметры xml_declaration и default_namespace.
Изменено в версии 3.8: Функция
tostringlist()теперь сохраняет порядок атрибутов, заданный пользователем.
- xml.etree.ElementTree.XML(text, parser=None)¶
Разбирает XML-раздел из строковой константы. Эту функцию можно использовать для встраивания «XML-литералов» в код Python. text – строка, содержащая XML-данные. parser – необязательный экземпляр анализатора. Если не указан, используется стандартный анализатор
XMLParser. Возвращает экземплярElement.
- xml.etree.ElementTree.XMLID(text, parser=None)¶
Разбирает XML-фрагмент из строковой константы и возвращает словарь, сопоставляющий идентификаторы элементов с элементами. text – строка, содержащая XML-данные. parser – необязательный экземпляр анализатора. Если он не указан, используется стандартный анализатор
XMLParser. Возвращает кортеж, содержащий экземплярElementи словарь.
Поддержка XInclude¶XInclude support
Этот модуль предоставляет ограниченную поддержку
директив XInclude через вспомогательный модуль xml.etree.ElementInclude. Этот модуль можно использовать для вставки поддеревьев и текстовых строк в деревья элементов на основе информации в дереве.
Пример¶Example
Вот пример, демонстрирующий использование модуля 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>
Ссылка¶Reference
Функции¶Functions
- xml.etree.ElementInclude.default_loader(href, parse, encoding=None)¶
Загрузчик по умолчанию. Этот загрузчик читает включаемый ресурс с диска. href – это URL. parse – режим разбора: «xml» или «text». encoding – необязательная текстовая кодировка. Если не указана, используется кодировка
utf-8. Возвращает развёрнутый ресурс. Если режим разбора –"xml", возвращается экземплярElement. Если режим разбора –"text", возвращается строка. Если загрузчику не удалось выполнить задачу, он может вернутьNoneили возбудить исключение.
- xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)¶
Эта функция разворачивает директивы XInclude на месте в дереве, на которое указывает elem. elem – это либо корневой
Element, либо экземплярElementTreeдля поиска такого элемента. loader – необязательный загрузчик ресурсов. Если опущен, по умолчанию используетсяdefault_loader(). Если задан, это должна быть вызываемая сущность, реализующая тот же интерфейс, что иdefault_loader(). base_url – базовый URL исходного файла для разрешения относительных ссылок на включаемые файлы. max_depth – максимальное количество рекурсивных включений. Ограничение введено для снижения риска «взрыва» вредоносного содержимого. ПередайтеNone, чтобы отключить ограничение.Изменено в версии 3.9: Добавлены параметры base_url и max_depth.
Объекты Element¶Element Objects
- class xml.etree.ElementTree.Element(tag, /, attrib={}, **extra)¶
Класс Element. Этот класс определяет интерфейс Element и предоставляет эталонную реализацию этого интерфейса.
Имя элемента, имена атрибутов и значения атрибутов могут быть либо байтовыми строками, либо строками Unicode. tag – имя элемента. attrib – необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные как именованные аргументы.
Изменено в версии 3.15: attrib теперь может быть
frozendict.Изменено в версии 3.15: tag теперь является только позиционным параметром.
- 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 может быть именем тега или path. Возвращает экземпляр элемента или
None. namespaces – необязательное отображение префикса пространства имён на полное имя. Передайте''в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в указанное пространство имён.
- findall(match, namespaces=None)¶
Находит все подходящие подэлементы по имени тега или path. Возвращает список, содержащий все подходящие элементы в порядке документа. namespaces – необязательное отображение префикса пространства имён на полное имя. Передайте
''в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в указанное пространство имён.
- findtext(match, default=None, namespaces=None)¶
Находит текст для первого подэлемента, соответствующего match. match может быть именем тега или path. Возвращает текстовое содержимое первого подходящего элемента или default, если элемент не найден. Обратите внимание: если у подходящего элемента нет текстового содержимого, возвращается пустая строка. namespaces – необязательное отображение префикса пространства имён на полное имя. Передайте
''в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в указанное пространство имён.
- insert(index, subelement)¶
Вставляет subelement в указанную позицию в этом элементе. Возбуждает
TypeError, если subelement не являетсяElement.
- iter(tag=None)¶
Создаёт древовидный итератор с текущим элементом в качестве корня. Итератор перебирает этот элемент и все элементы ниже него в порядке документа (сначала в глубину). Если tag не равен
Noneили'*', из итератора возвращаются только элементы, тег которых равен tag. Если структура дерева изменяется во время итерации, результат не определён.Добавлено в версии 3.2.
- iterfind(match, namespaces=None)¶
Находит все подходящие подэлементы по имени тега или path. Возвращает итерируемый объект, выдающий все подходящие элементы в порядке документа. namespaces – необязательное отображение префикса пространства имён на полное имя.
Добавлено в версии 3.2.
- itertext()¶
Создаёт текстовый итератор. Итератор перебирает этот элемент и все подэлементы в порядке документа и возвращает весь внутренний текст.
Добавлено в версии 3.2.
- makeelement(tag, attrib)¶
Создаёт новый объект элемента того же типа, что и этот элемент. Не вызывайте этот метод, используйте вместо него фабричную функцию
SubElement().
- remove(subelement)¶
Удаляет subelement из элемента. В отличие от методов find*, этот метод сравнивает элементы по идентичности экземпляра, а не по значению тега или содержимому.
Объекты
Elementтакже поддерживают следующие методы последовательностей для работы с подэлементами:__delitem__(),__getitem__(),__setitem__(),__len__().Внимание: элементы без подэлементов в логическом контексте дают
False. В будущей версии Python все элементы будут даватьTrueнезависимо от наличия подэлементов. Вместо этого рекомендуется использовать явные проверкиlen(elem)илиelem is not None.element = root.find('foo') if not element: # осторожно! print("element not found, or element has no subelements") if element is None: print("element not found")
Изменено в версии 3.12: Проверка истинности элемента теперь вызывает
DeprecationWarning.До Python 3.8 порядок сериализации XML-атрибутов элементов искусственно делался предсказуемым за счёт сортировки атрибутов по имени. Опираясь на теперь гарантированный порядок словарей, это произвольное переупорядочивание было удалено в Python 3.8, чтобы сохранять тот порядок, в котором атрибуты были исходно разобраны или созданы пользовательским кодом.
В целом пользовательскому коду не следует полагаться на определённый порядок атрибутов, поскольку набор XML-информации явно исключает порядок атрибутов из передачи информации. Код должен быть готов обрабатывать любой порядок на входе. В случаях, когда требуется детерминированный вывод XML, например для криптографической подписи или тестовых наборов данных, доступна каноническая сериализация с помощью функции
canonicalize().В случаях, когда канонический вывод неприменим, но определённый порядок атрибутов всё же желателен, коду следует стремиться создавать атрибуты непосредственно в нужном порядке, чтобы избежать несоответствий для читающих код. Если это трудно реализовать, можно применить следующий приём перед сериализацией, чтобы задать порядок независимо от создания элемента:
def reorder_attributes(root): for el in root.iter(): attrib = el.attrib if len(attrib) > 1: # измените порядок атрибутов, например, сортировкой attribs = sorted(attrib.items()) attrib.clear() attrib.update(attribs)
Объекты ElementTree¶ElementTree Objects
- 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") # Находит первое вхождение тега p в body
>>> p
<Element 'p' at 0xb77ec26c>
>>> links = list(p.iter("a")) # Возвращает список всех ссылок
>>> links
[<Element 'a' at 0xb77ec2ac>, <Element 'a' at 0xb77ec1cc>]
>>> for i in links: # Перебирает все найденные ссылки
... i.attrib["target"] = "blank"
...
>>> tree.write("output.xhtml")
Объекты QName¶QName Objects
- 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¶TreeBuilder Objects
- 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, если задан, должен быть вызываемым объектом, принимающим два позиционных аргумента: tag и словарь атрибутов. Ожидается, что он вернёт новый экземпляр элемента.
Функции comment_factory и pi_factory, если заданы, должны вести себя как функции
Comment()иProcessingInstruction()для создания комментариев и инструкций обработки. Если они не заданы, используются фабрики по умолчанию. Если insert_comments и/или insert_pis равно true, комментарии/инструкции обработки будут вставлены в дерево, если они появляются внутри корневого элемента (но не вне его).- close()¶
Сбрасывает буферы построителя и возвращает элемент верхнего уровня документа. Возвращает экземпляр
Element.
- data(data)¶
Добавляет текст в текущий элемент. data является строкой. Это должна быть либо байтовая строка, либо строка Unicode.
- end(tag)¶
Закрывает текущий элемент. tag – имя элемента. Возвращает закрытый элемент.
- start(tag, attrs)¶
Открывает новый элемент. tag – имя элемента. attrs – словарь, содержащий атрибуты элемента. Возвращает открытый элемент.
- comment(text)¶
Создаёт комментарий с заданным text. Если
insert_commentsравно true, он также будет добавлен в дерево.Добавлено в версии 3.8.
- pi(target, text)¶
Создаёт инструкцию обработки с заданным именем target и text. Если
insert_pisравно true, она также будет добавлена в дерево.Добавлено в версии 3.8.
Кроме того, пользовательский объект
TreeBuilderможет предоставлять следующие методы:- doctype(name, pubid, system)¶
Обрабатывает объявление doctype. name – имя doctype. pubid – публичный идентификатор. system – системный идентификатор. Этот метод не существует в классе
TreeBuilderпо умолчанию.Добавлено в версии 3.2.
- start_ns(prefix, uri)¶
Вызывается всякий раз, когда парсер встречает новое объявление пространства имён, перед колбэком
start()для открывающего элемента, который его определяет. prefix равен''для пространства имён по умолчанию и имени объявленного префикса пространства имён в противном случае. uri – URI пространства имён.Добавлено в версии 3.8.
- end_ns(prefix)¶
Вызывается после колбэка
end()элемента, который объявил отображение префикса пространства имён, с именем prefix, вышедшего из области видимости.Добавлено в версии 3.8.
- class xml.etree.ElementTree.C14NWriterTarget(write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None)¶
Писатель C14N 2.0. Аргументы такие же, как у функции
canonicalize(). Этот класс не строит дерево, а преобразует события колбэков напрямую в сериализованную форму с помощью функции write.Добавлено в версии 3.8.
Объекты XMLParser¶XMLParser Objects
- class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)¶
Этот класс является низкоуровневым строительным блоком модуля. Он использует
xml.parsers.expatдля эффективного, основанного на событиях разбора XML. В него можно по частям подавать XML-данные с помощью методаfeed(), а события разбора преобразуются в push-API путём вызова колбэков на объекте target. Если target опущен, используется стандартныйTreeBuilder. Если задан encoding [1], значение переопределяет кодировку, указанную в XML-файле.Изменено в версии 3.8: Параметры теперь только ключевые. Аргумент html больше не поддерживается.
- close()¶
Завершает передачу данных парсеру. Возвращает результат вызова метода
close()цели, переданной при создании; по умолчанию это корневой элемент документа.
- feed(data)¶
Передает данные парсеру. data – это закодированные данные.
- flush()¶
Запускает разбор любых ранее переданных, но еще не разобранных данных. Это может использоваться для обеспечения более оперативной обратной связи, особенно с Expat >=2.6.0. Реализация
flush()временно отключает отложенный переразбор в Expat (если он включен) и запускает переразбор. Отключение отложенного переразбора имеет последствия для безопасности; подробнее см.xml.parsers.expat.xmlparser.SetReparseDeferralEnabled().flush()была перенесена в некоторые предыдущие выпуски CPython как исправление безопасности. Проверьте доступность с помощьюhasattr(), если код работает на разных версиях Python.Добавлено в версии 3.13.
XMLParser.feed()вызывает метод целиstart(tag, attrs_dict)для каждого открывающего тега, методend(tag)– для каждого закрывающего тега, а данные обрабатываются методомdata(data). Дополнительные поддерживаемые методы колбэков см. в классеTreeBuilder.XMLParser.close()вызывает метод целиclose().XMLParserможет использоваться не только для построения древовидной структуры. Ниже приведен пример подсчета максимальной глубины XML-файла:>>> from xml.etree.ElementTree import XMLParser >>> class MaxDepth: # Целевой объект парсера ... maxDepth = 0 ... depth = 0 ... def start(self, tag, attrib): # Вызывается для каждого открывающего тега. ... self.depth += 1 ... if self.depth > self.maxDepth: ... self.maxDepth = self.depth ... def end(self, tag): # Вызывается для каждого закрывающего тега. ... self.depth -= 1 ... def data(self, data): ... pass # С данными ничего делать не нужно. ... def close(self): # Вызывается, когда все данные проанализированы. ... return self.maxDepth ... >>> target = MaxDepth() >>> parser = XMLParser(target=target) >>> exampleXml = """ ... <a> ... <b> ... </b> ... <b> ... <c> ... <d> ... </d> ... </c> ... </b> ... </a>""" >>> parser.feed(exampleXml) >>> parser.close() 4
Объекты XMLPullParser¶XMLPullParser Objects
- 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)¶
Передает парсеру данные в виде байтов.
- flush()¶
Запускает разбор любых ранее переданных, но еще не разобранных данных. Это может использоваться для обеспечения более оперативной обратной связи, особенно с Expat >=2.6.0. Реализация
flush()временно отключает отложенный переразбор в Expat (если он включен) и запускает переразбор. Отключение отложенного переразбора имеет последствия для безопасности; подробнее см.xml.parsers.expat.xmlparser.SetReparseDeferralEnabled().flush()была перенесена в некоторые предыдущие выпуски CPython как исправление безопасности. Проверьте доступность с помощьюhasattr(), если код работает на разных версиях Python.Добавлено в версии 3.13.
- close()¶
Сигнализирует парсеру, что поток данных завершен. В отличие от
XMLParser.close(), этот метод всегда возвращаетNone. Любые события, еще не извлеченные на момент закрытия парсера, все еще можно прочитать с помощьюread_events().
- read_events()¶
Возвращает итератор по событиям, которые были обнаружены в данных, переданных парсеру. Итератор выдает пары
(event, elem), где event – строка, представляющая тип события (например,"end"), а elem – обнаруженный объектElementили другое контекстное значение, как указано ниже.start,end: текущий элемент.comment,pi: текущий комментарий / инструкция по обработке.start-ns: кортеж(prefix, uri), именующий объявленное пространство имен.end-ns:None(может измениться в будущей версии).
События, предоставленные в предыдущем вызове
read_events(), не будут возвращены снова. События потребляются из внутренней очереди только при извлечении из итератора, поэтому несколько читателей, параллельно выполняющих итерацию по итераторам, полученным изread_events(), будут иметь непредсказуемые результаты.
Примечание
XMLPullParserгарантирует только, что при генерации события "start" был обнаружен символ ">" открывающего тега, поэтому атрибуты определены, но содержимое атрибутов text и tail на этом этапе не определено. То же самое относится и к дочерним элементам: они могут присутствовать, а могут и нет.Если нужен полностью заполненный элемент, используйте события "end".
Добавлено в версии 3.4.
Изменено в версии 3.8: Были добавлены события
commentиpi.
Исключения¶Exceptions
- class xml.etree.ElementTree.ParseError¶
Ошибка разбора XML, возникающая при сбое разбора в различных методах разбора этого модуля. Строковое представление экземпляра этого исключения будет содержать понятное пользователю сообщение об ошибке. Кроме того, будут доступны следующие атрибуты:
- code¶
Числовой код ошибки от парсера expat. Список кодов ошибок и их значений см. в документации
xml.parsers.expat.
- position¶
Кортеж из номеров строки line и столбца column, указывающий, где произошла ошибка.
Сноски
Эта страница – перевод. Оригинал на английском – docs.python.org. Нашли неточность? Сообщите нам.