xml.etree.ElementTree — The ElementTree XML API

Вихідний код: Lib/xml/etree/ElementTree.py


Модуль xml.etree.ElementTree реалізує простий і ефективний API для аналізу та створення даних XML.

Змінено в версії 3.3: Цей модуль використовуватиме швидку реалізацію, якщо вона доступна.

Застаріло починаючи з версії 3.3: The xml.etree.cElementTree module is deprecated.

Попередження

Модуль xml.etree.ElementTree не захищений від зловмисно створених даних. Якщо вам потрібно проаналізувати ненадійні або неавтентифіковані дані, перегляньте Уразливості XML.

Підручник

Це короткий посібник із використання xml.etree.ElementTree (коротко ET). Мета полягає в тому, щоб продемонструвати деякі будівельні блоки та основні концепції модуля.

Дерево та елементи XML

XML за своєю суттю є ієрархічним форматом даних, і найприроднішим способом його представлення є дерево. ET має два класи для цієї мети - ElementTree представляє весь XML-документ у вигляді дерева, а Element представляє окремий вузол у цьому дереві. Взаємодія з усім документом (читання та запис до/з файлів) зазвичай здійснюється на рівні ElementTree. Взаємодія з одним елементом XML і його піделементами здійснюється на рівні Element.

Розбір XML

We’ll be using the fictive country_data.xml XML document as the sample data for this section:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

Ми можемо імпортувати ці дані, зчитуючи з файлу:

import xml.etree.ElementTree as ET
tree = ET.parse('country_data.xml')
root = tree.getroot()

Або безпосередньо з рядка:

root = ET.fromstring(country_data_as_string)

fromstring() аналізує XML із рядка безпосередньо в Element, який є кореневим елементом проаналізованого дерева. Інші функції аналізу можуть створити ElementTree. Перевірте документацію, щоб переконатися.

Як Element, root має тег і словник атрибутів:

>>> root.tag
'data'
>>> root.attrib
{}

Він також має дочірні вузли, по яких ми можемо повторювати:

>>> for child in root:
...     print(child.tag, child.attrib)
...
country {'name': 'Liechtenstein'}
country {'name': 'Singapore'}
country {'name': 'Panama'}

Дочірні вузли є вкладеними, і ми можемо отримати доступ до певних дочірніх вузлів за індексом:

>>> root[0][1].text
'2008'

Примітка

Не всі елементи XML-введення стануть елементами проаналізованого дерева. Наразі цей модуль пропускає будь-які коментарі XML, інструкції з обробки та оголошення типу документів у вхідних даних. Тим не менш, дерева, створені за допомогою API цього модуля, а не синтаксичного аналізу тексту XML, можуть містити коментарі та інструкції з обробки; вони будуть включені під час генерації вихідних даних XML. Оголошення типу документа можна отримати, передавши спеціальний екземпляр TreeBuilder конструктору XMLParser.

Pull API для неблокуючого аналізу

Більшість функцій синтаксичного аналізу, наданих цим модулем, вимагають одночасного читання всього документа перед поверненням будь-якого результату. Можна використовувати XMLParser і подавати дані в нього поступово, але це API push, який викликає методи в цілі зворотного виклику, що є надто низьким рівнем і незручним для більшості потреб. Іноді користувач справді хоче мати можливість поступово аналізувати XML без блокування операцій, насолоджуючись при цьому зручністю повністю сконструйованих об’єктів Element.

Найпотужнішим інструментом для цього є XMLPullParser. Він не потребує блокуючого читання для отримання XML-даних, натомість дані подаються поступово за допомогою викликів XMLPullParser.feed(). Щоб отримати проаналізовані елементи XML, викличте XMLPullParser.read_events(). Ось приклад:

>>> parser = ET.XMLPullParser(['start', 'end'])
>>> parser.feed('<mytag>sometext')
>>> list(parser.read_events())
[('start', <Element 'mytag' at 0x7fa66db2be58>)]
>>> parser.feed(' more text</mytag>')
>>> for event, elem in parser.read_events():
...     print(event)
...     print(elem.tag, 'text=', elem.text)
...
end
mytag text= sometext more text

Очевидним варіантом використання є додатки, які працюють без блокування, коли XML-дані надходять із сокета або зчитуються поступово з якогось пристрою зберігання даних. У таких випадках блокування читання неприпустимо.

Оскільки він дуже гнучкий, XMLPullParser може бути незручним у використанні для простіших випадків використання. Якщо ви не заперечуєте, що ваша програма блокує читання XML-даних, але все одно хочете мати можливості поступового аналізу, подивіться на iterparse(). Це може бути корисно, коли ви читаєте великий XML-документ і не хочете повністю тримати його в пам’яті.

Where immediate feedback through events is wanted, calling method XMLPullParser.flush() can help reduce delay; please make sure to study the related security notes.

Пошук цікавих елементів

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 до елемента rank:

>>> 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 або dicts. Таким чином, приклад спочатку збирає всі відповідні елементи за допомогою 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, який містить два простори імен, один із префіксом «вигаданий», а інший — простір імен за умовчанням:

<?xml version="1.0"?>
<actors xmlns:fictional="http://characters.example.com"
        xmlns="http://people.example.com">
    <actor>
        <name>John Cleese</name>
        <fictional:character>Lancelot</fictional:character>
        <fictional:character>Archie Leach</fictional:character>
    </actor>
    <actor>
        <name>Eric Idle</name>
        <fictional:character>Sir Robin</fictional:character>
        <fictional:character>Gunther</fictional:character>
        <fictional:character>Commander Clement</fictional:character>
    </actor>
</actors>

Один із способів пошуку та вивчення цього прикладу XML — це вручну додати URI до кожного тегу чи атрибута в xpath find() або findall():

root = fromstring(xml_text)
for actor in root.findall('{http://people.example.com}actor'):
    name = actor.find('{http://people.example.com}name')
    print(name.text)
    for char in actor.findall('{http://characters.example.com}character'):
        print(' |-->', char.text)

Кращий спосіб пошуку у прикладі XML із простором імен — створити словник із власними префіксами та використовувати їх у функціях пошуку:

ns = {'real_person': 'http://people.example.com',
      'role': 'http://characters.example.com'}

for actor in root.findall('real_person:actor', ns):
    name = actor.find('real_person:name', ns)
    print(name.text)
    for char in actor.findall('role:character', ns):
        print(' |-->', char.text)

Ці два підходи виводять:

John Cleese
 |--> Lancelot
 |--> Archie Leach
Eric Idle
 |--> Sir Robin
 |--> Gunther
 |--> Commander Clement

Підтримка XPath

Цей модуль забезпечує обмежену підтримку виразів XPath для пошуку елементів у дереві. Метою є підтримка невеликої підмножини скороченого синтаксису; повний механізм XPath виходить за рамки модуля.

приклад

Ось приклад, який демонструє деякі можливості модуля XPath. Ми будемо використовувати XML-документ countrydata з розділу Parsing 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

Синтаксис

Значення

тег

Вибирає всі дочірні елементи з заданим тегом. Наприклад, spam вибирає всі дочірні елементи з іменем spam, а spam/egg вибирає всіх онуків з іменем egg у всіх дочірніх елементах з іменем spam. {namespace}* вибирає всі теги в заданому просторі імен, {*}spam вибирає теги з назвою spam у будь-якому просторі імен (або без нього), а {}* лише вибирає теги, які не знаходяться в просторі імен.

Змінено в версії 3.8: Додано підтримку символів підстановки зірок.

*

Вибирає всі дочірні елементи, включаючи коментарі та інструкції з обробки. Наприклад, */egg вибирає всіх онуків з іменем egg.

.

Вибирає поточний вузол. Це здебільшого корисно на початку шляху, щоб вказати, що це відносний шлях.

//

Вибирає всі піделементи на всіх рівнях під поточним елементом. Наприклад, .//egg вибирає всі елементи egg у всьому дереві.

..

Вибирає батьківський елемент. Повертає None, якщо шлях намагається досягти предків початкового елемента (був викликаний елемент find).

[@attrib]

Вибирає всі елементи, які мають заданий атрибут.

[@attrib='value']

Вибирає всі елементи, для яких даний атрибут має задане значення. Значення не може містити лапки.

[@attrib!='value']

Вибирає всі елементи, для яких даний атрибут не має заданого значення. Значення не може містити лапки.

Added in version 3.10.

[тег]

Вибирає всі елементи, які мають дочірні елементи з іменем tag. Утримуються лише найближчі діти.

[.='текст']

Вибирає всі елементи, повний текстовий вміст яких, включаючи нащадків, дорівнює заданому тексту.

Added in version 3.7.

[.!='текст']

Вибирає всі елементи, повний текстовий вміст яких, включно з нащадками, не відповідає заданому тексту.

Added in version 3.10.

[tag='text']

Вибирає всі елементи, які мають дочірні елементи з назвою tag, повний текстовий вміст яких, включаючи нащадків, дорівнює заданому text.

[tag!='text']

Вибирає всі елементи, які мають дочірні елементи з іменем tag, повний текстовий вміст яких, включаючи нащадків, не збігається з заданим text.

Added in version 3.10.

[позиція]

Вибирає всі елементи, які розташовані на заданій позиції. Позиція може бути цілим числом (1 — перша позиція), виразом last() (для останньої позиції) або позицією відносно останньої позиції (наприклад, last()-1 ).

Предикати (вирази в квадратних дужках) мають передувати назві тегу, зірочці або іншому предикату. Предикатам position має передувати ім’я тегу.

довідка

Функції

xml.etree.ElementTree.canonicalize(xml_data=None, *, out=None, from_file=None, **options)

C14N 2.0 функція перетворення.

Canonicalization is a way to normalise XML output in a way that allows byte-by-byte comparisons and digital signatures. It reduces the freedom that XML serializers have and instead generates a more constrained XML representation. The main restrictions regard the placement of namespace declarations, the ordering of attributes, and ignorable whitespace.

Ця функція приймає рядок XML-даних (xml_data) або шлях до файлу або файлоподібний об’єкт (from_file) як вхідні дані, перетворює їх у канонічну форму та записує за допомогою out file(-like) об’єкт, якщо він наданий, або повертає його як текстовий рядок, якщо ні. Вихідний файл отримує текст, а не байти. Тому його слід відкривати в текстовому режимі з кодуванням 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)

Параметри конфігурації такі:

  • 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: набір імен тегів, які не повинні бути серіалізовані

У наведеному вище списку параметрів «набір» відноситься до будь-якої колекції або ітерації рядків, упорядкування не очікується.

Added in version 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(). текст — це рядок, що містить дані XML. parser є необов’язковим екземпляром парсера. Якщо не вказано, використовується стандартний аналізатор XMLParser. Повертає екземпляр Element.

xml.etree.ElementTree.fromstringlist(sequence, parser=None)

Розбирає XML-документ із послідовності фрагментів рядків. послідовність — це список або інша послідовність, що містить фрагменти даних XML. parser є необов’язковим екземпляром парсера. Якщо не вказано, використовується стандартний аналізатор XMLParser. Повертає екземпляр Element.

Added in version 3.2.

xml.etree.ElementTree.indent(tree, space='  ', level=0)

До піддерева додає пробіли для візуального відступу дерева. Це можна використати для генерації красивого друкованого виводу XML. дерево може бути елементом або деревом елементів. пробіл — це пробільний рядок, який буде вставлено для кожного рівня відступу, два символи пробілу за замовчуванням. Для відступу часткових піддерев усередині дерева з відступами передайте початковий рівень відступу як level.

Added in version 3.9.

xml.etree.ElementTree.iselement(element)

Перевірте, чи об’єкт є дійсним об’єктом елемента. element — екземпляр елемента. Повертає True, якщо це об’єкт елемента.

xml.etree.ElementTree.iterparse(source, events=None, parser=None)

Parses an XML section into an element tree incrementally, and reports what’s going on to the user. source is a filename or file object containing XML data. events is a sequence of events to report back. The supported events are the strings "start", "end", "comment", "pi", "start-ns" and "end-ns" (the «ns» events are used to get detailed namespace information). If events is omitted, only "end" events are reported. parser is an optional parser instance. If not given, the standard XMLParser parser is used. parser must be a subclass of XMLParser and can only use the default TreeBuilder as a target. Returns an iterator providing (event, elem) pairs; it has a root attribute that references the root element of the resulting XML tree once source is fully read. The iterator has the close() method that closes the internal file object if source is a filename.

Зауважте, що хоча iterparse() будує дерево поступово, він блокує читання source (або файлу, який він називає). Таким чином, він не підходить для додатків, де блокування зчитування неможливе. Повністю неблокуючий аналіз див. XMLPullParser.

Примітка

iterparse() лише гарантує, що він побачив символ «>» початкового тегу, коли він випромінює подію «start», тому атрибути визначені, але вміст атрибутів text і tail на цьому етапі не визначено . Те саме стосується елемента діти; вони можуть бути або не бути присутніми.

Якщо вам потрібен повністю заповнений елемент, шукайте події «кінець».

Застаріло починаючи з версії 3.4: Аргумент parser.

Змінено в версії 3.8: Додано події comment і pi.

Змінено в версії 3.13: Added the close() method.

xml.etree.ElementTree.parse(source, parser=None)

Розбирає розділ XML у дерево елементів. джерело — це ім’я файлу або об’єкт файлу, що містить дані XML. parser є необов’язковим екземпляром парсера. Якщо не вказано, використовується стандартний аналізатор XMLParser. Повертає екземпляр ElementTree.

xml.etree.ElementTree.ProcessingInstruction(target, text=None)

Завод ПІ-елементів. Ця фабрична функція створює спеціальний елемент, який буде серіалізовано як інструкцію обробки XML. target — це рядок, що містить ціль PI. текст — це рядок, що містить вміст PI, якщо його вказано. Повертає екземпляр елемента, що представляє інструкцію обробки.

Note that XMLParser skips over processing instructions in the input instead of creating PI objects for them. An ElementTree will only contain processing instruction nodes if they have been inserted into to the tree using one of the Element methods.

xml.etree.ElementTree.register_namespace(prefix, uri)

Реєструє префікс простору імен. Реєстр є глобальним, і будь-яке існуюче відображення для заданого префікса або URI простору імен буде видалено. префікс — це префікс простору імен. uri — це uri простору імен. Теги й атрибути в цьому просторі імен будуть серіалізовані з заданим префіксом, якщо це взагалі можливо.

Added in version 3.2.

xml.etree.ElementTree.SubElement(parent, tag, attrib={}, **extra)

Піделементний завод. Ця функція створює екземпляр елемента та додає його до існуючого елемента.

Ім’я елемента, назви атрибутів і значення атрибутів можуть бути байтовими рядками або рядками Unicode. parent є батьківським елементом. тег — це назва піделемента. 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. кодування [1] — вихідне кодування (за замовчуванням — US-ASCII). Використовуйте encoding="unicode", щоб створити рядок Юнікод (інакше буде згенеровано байтовий рядок). method — це "xml", "html" або "text" (за замовчуванням "xml"). xml_declaration, default_namespace і short_empty_elements мають те саме значення, що й у ElementTree.write(). Повертає (необов’язково) закодований рядок, що містить дані XML.

Змінено в версії 3.4: Added the short_empty_elements parameter.

Змінено в версії 3.8: Added the xml_declaration and default_namespace parameters.

Змінено в версії 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. кодування [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).

Added in version 3.2.

Змінено в версії 3.4: Added the short_empty_elements parameter.

Змінено в версії 3.8: Added the xml_declaration and default_namespace parameters.

Змінено в версії 3.8: Функція tostringlist() тепер зберігає порядок атрибутів, указаний користувачем.

xml.etree.ElementTree.XML(text, parser=None)

Розбирає розділ XML із константи рядка. Цю функцію можна використовувати для вбудовування «XML-літералів» у код Python. текст — це рядок, що містить дані XML. parser є необов’язковим екземпляром парсера. Якщо не вказано, використовується стандартний аналізатор XMLParser. Повертає екземпляр Element.

xml.etree.ElementTree.XMLID(text, parser=None)

Розбирає розділ XML із константи рядка, а також повертає словник, який відображає ідентифікатори елемента: елементи. текст — це рядок, що містить дані 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)

Default loader. This default loader reads an included resource from disk. href is a URL. parse is for parse mode either «xml» or «text». encoding is an optional text encoding. If not given, encoding is utf-8. Returns the expanded resource. If the parse mode is "xml", this is an Element instance. If the parse mode is "text", this is a string. If the loader fails, it can return None or raise an exception.

xml.etree.ElementInclude.include(elem, loader=None, base_url=None, max_depth=6)

This function expands XInclude directives in-place in tree pointed by elem. elem is either the root Element or an ElementTree instance to find such element. loader is an optional resource loader. If omitted, it defaults to default_loader(). If given, it should be a callable that implements the same interface as default_loader(). base_url is base URL of the original file, to resolve relative include file references. max_depth is the maximum number of recursive inclusions. Limited to reduce the risk of malicious content explosion. Pass None to disable the limitation.

Змінено в версії 3.9: Added the base_url and max_depth parameters.

Об’єкти елементів

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)

Клас елемента. Цей клас визначає інтерфейс Element і забезпечує еталонну реалізацію цього інтерфейсу.

Ім’я елемента, назви атрибутів і значення атрибутів можуть бути байтовими рядками або рядками Unicode. тег — це назва елемента. 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" і tail None, а елемент d має text None і 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)

Appends subelements from an iterable of elements. Raises TypeError if a subelement is not an Element.

Added in version 3.2.

find(match, namespaces=None)

Знаходить перший піделемент, що відповідає match. match може бути назвою тегу або шляхом. Повертає екземпляр елемента або None. простори імен — це необов’язкове відображення префікса простору імен на повне ім’я. Передайте '' як префікс, щоб перемістити всі імена тегів без префіксів у виразі до вказаного простору імен.

findall(match, namespaces=None)

Знаходить усі відповідні піделементи за назвою тегу або шляхом. Повертає список, що містить усі відповідні елементи в порядку документа. простори імен — це необов’язкове відображення префікса простору імен на повне ім’я. Передайте '' як префікс, щоб перемістити всі імена тегів без префіксів у виразі до вказаного простору імен.

findtext(match, default=None, namespaces=None)

Знаходить текст для першого піделемента, який відповідає match. match може бути назвою тегу або шляхом. Повертає текстовий вміст першого відповідного елемента або за замовчуванням, якщо елемент не знайдено. Зауважте, що якщо відповідний елемент не має текстового вмісту, повертається порожній рядок. простори імен — це необов’язкове відображення префікса простору імен на повне ім’я. Передайте '' як префікс, щоб перемістити всі імена тегів без префіксів у виразі до вказаного простору імен.

insert(index, subelement)

Вставляє піделемент у задану позицію цього елемента. Викликає TypeError, якщо subelement не є Element.

iter(tag=None)

Створює дерево iterator з поточним елементом як коренем. Ітератор повторює цей елемент і всі елементи під ним у порядку документа (спочатку глибина). Якщо tag не є None або '*', ітератор повертає лише елементи, тег яких дорівнює tag. Якщо структуру дерева змінено під час ітерації, результат буде невизначеним.

Added in version 3.2.

iterfind(match, namespaces=None)

Знаходить усі відповідні піделементи за назвою тегу або шляхом. Повертає iterable, що дає всі відповідні елементи в порядку документа. простори імен — це необов’язкове відображення префікса простору імен на повне ім’я.

Added in version 3.2.

itertext()

Створює текстовий ітератор. Ітератор проходить по цьому елементу та всім піделементам у порядку документа та повертає весь внутрішній текст.

Added in version 3.2.

makeelement(tag, attrib)

Створює новий об’єкт елемента того самого типу, що й цей елемент. Не викликайте цей метод, замість цього використовуйте фабричну функцію SubElement().

remove(subelement)

Видаляє піделемент з елемента. На відміну від методів find*, цей метод порівнює елементи на основі ідентичності екземпляра, а не на основі значення тегу чи вмісту.

Об’єкти Element також підтримують такі методи типу послідовності для роботи з піделементами: __delitem__(), __getitem__(), __setitem__(), __len__().

Caution: Elements with no subelements will test as False. In a future release of Python, all elements will test as True regardless of whether subelements exist. Instead, prefer explicit len(elem) or elem is not None tests.:

element = root.find('foo')

if not element:  # careful!
    print("element not found, or element has no subelements")

if element is None:
    print("element not found")

Змінено в версії 3.12: Testing the truth value of an Element emits 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:
            # 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)

Створює та повертає ітератор дерева для кореневого елемента. Ітератор перебирає всі елементи в цьому дереві в порядку секцій. тег — це тег, який потрібно шукати (за замовчуванням повертаються всі елементи).

iterfind(match, namespaces=None)

Те саме, що Element.iterfind(), починаючи з кореня дерева.

Added in version 3.2.

parse(source, parser=None)

Завантажує зовнішній розділ XML у це дерево елементів. джерело — це ім’я файлу або file object. parser є необов’язковим екземпляром парсера. Якщо не вказано, використовується стандартний аналізатор XMLParser. Повертає кореневий елемент розділу.

write(file, encoding='us-ascii', xml_declaration=None, default_namespace=None, method='xml', *, short_empty_elements=True)

Записує дерево елементів у файл як XML. file — це ім’я файлу або file object, відкритий для запису. кодування [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. Якщо кодування є "юнікодом", результатом є рядок; інакше це двійковий файл. Зауважте, що це може конфліктувати з типом file, якщо це відкритий file object; переконайтеся, що ви не намагаєтесь записати рядок у двійковий потік і навпаки.

Змінено в версії 3.4: Added the short_empty_elements parameter.

Змінено в версії 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 або, якщо вказано аргумент тегу, частину URI QName. Якщо вказано тег, перший аргумент інтерпретується як URI, а цей аргумент інтерпретується як локальне ім’я. Екземпляри QName є непрозорими.

Об’єкти TreeBuilder

class xml.etree.ElementTree.TreeBuilder(element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False)

Загальний конструктор структур елемента. Цей конструктор перетворює послідовність викликів методу початку, даних, кінця, коментаря та pi у добре сформовану структуру елементів. Ви можете використовувати цей клас, щоб побудувати структуру елемента за допомогою спеціального синтаксичного аналізатора XML або іншого XML-подібного формату.

element_factory, якщо задано, має бути викликом, що приймає два позиційні аргументи: тег і dict атрибутів. Очікується, що він поверне новий екземпляр елемента.

Функції comment_factory і pi_factory, якщо їх надано, повинні поводитися як функції Comment() і ProcessingInstruction() для створення коментарів і інструкцій з обробки. Якщо не вказано, будуть використані фабрики за замовчуванням. Якщо insert_comments і/або insert_pis має значення true, коментарі/pis буде вставлено в дерево, якщо вони з’являться в кореневому елементі (але не поза ним).

close()

Очищає буфери конструктора та повертає елемент документа верхнього рівня. Повертає екземпляр Element.

data(data)

Додає текст до поточного елемента. data — це рядок. Це має бути байтовий рядок або рядок Unicode.

end(tag)

Закриває поточний елемент. тег — це назва елемента. Повертає закритий елемент.

start(tag, attrs)

Відкриває новий елемент. тег — це назва елемента. attrs — це словник, що містить атрибути елементів. Повертає відкритий елемент.

comment(text)

Створює коментар із заданим текстом. Якщо insert_comments має значення true, це також додасть його до дерева.

Added in version 3.8.

pi(target, text)

Creates a process instruction with the given target name and text. If insert_pis is true, this will also add it to the tree.

Added in version 3.8.

Крім того, спеціальний об’єкт TreeBuilder може надавати такі методи:

doctype(name, pubid, system)

Обробляє оголошення doctype. name — це ім’я типу документа. pubid є публічним ідентифікатором. system — це ідентифікатор системи. Цей метод не існує в класі TreeBuilder за замовчуванням.

Added in version 3.2.

start_ns(prefix, uri)

Викликається кожного разу, коли синтаксичний аналізатор зустрічає нове оголошення простору імен перед зворотним викликом start() для початкового елемента, який його визначає. префікс — це '' для простору імен за замовчуванням, а в інших випадках – оголошене ім’я префікса простору імен. uri — URI простору імен.

Added in version 3.8.

end_ns(prefix)

Викликається після зворотного виклику end() елемента, який оголосив відображення префікса простору імен, з назвою префікса, який вийшов за межі області видимості.

Added in version 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.

Added in version 3.8.

Об’єкти XMLParser

class xml.etree.ElementTree.XMLParser(*, target=None, encoding=None)

Цей клас є будівельним блоком низького рівня модуля. Він використовує xml.parsers.expat для ефективного аналізу XML на основі подій. Він може передавати XML-дані поетапно за допомогою методу feed(), а події синтаксичного аналізу транслюються в push API шляхом виклику зворотних викликів для об’єкта target. Якщо target опущено, використовується стандартний TreeBuilder. Якщо вказано кодування [1], значення має перевагу над кодуванням, указаним у файлі XML.

Змінено в версії 3.8: Parameters are now keyword-only. The html argument is no longer supported.

close()

Завершує подачу даних до аналізатора. Повертає результат виклику методу close() target, переданого під час створення; за замовчуванням це елемент документа верхнього рівня.

feed(data)

Подає дані в аналізатор. data — це закодовані дані.

flush()

Triggers parsing of any previously fed unparsed data, which can be used to ensure more immediate feedback, in particular with Expat >=2.6.0. The implementation of flush() temporarily disables reparse deferral with Expat (if currently enabled) and triggers a reparse. Disabling reparse deferral has security consequences; please see xml.parsers.expat.xmlparser.SetReparseDeferralEnabled() for details.

Note that flush() has been backported to some prior releases of CPython as a security fix. Check for availability of flush() using hasattr() if used in code running across a variety of Python versions.

Added in version 3.13.

XMLParser.feed() викликає метод target start(tag, attrs_dict) для кожного початкового тегу, його метод end(tag) для кожного закриваючого тегу, і дані обробляються методом дані(дані). Інші підтримувані методи зворотного виклику див. у класі TreeBuilder. XMLParser.close() викликає метод target close(). XMLParser можна використовувати не тільки для побудови деревовидної структури. Це приклад підрахунку максимальної глибини файлу XML:

>>> from xml.etree.ElementTree import XMLParser
>>> class MaxDepth:                     # The target object of the parser
...     maxDepth = 0
...     depth = 0
...     def start(self, tag, attrib):   # Called for each opening tag.
...         self.depth += 1
...         if self.depth > self.maxDepth:
...             self.maxDepth = self.depth
...     def end(self, tag):             # Called for each closing tag.
...         self.depth -= 1
...     def data(self, data):
...         pass            # We do not need to do anything with data.
...     def close(self):    # Called when all data has been parsed.
...         return self.maxDepth
...
>>> target = MaxDepth()
>>> parser = XMLParser(target=target)
>>> exampleXml = """
... <a>
...   <b>
...   </b>
...   <b>
...     <c>
...       <d>
...       </d>
...     </c>
...   </b>
... </a>"""
>>> parser.feed(exampleXml)
>>> parser.close()
4

Об’єкти XMLPullParser

class xml.etree.ElementTree.XMLPullParser(events=None)

Синтаксичний аналізатор, що підходить для неблокуючих програм. Його API на стороні введення схожий на API XMLParser, але замість того, щоб надсилати виклики до цілі зворотного виклику, XMLPullParser збирає внутрішній список подій аналізу та дозволяє користувачеві читати з нього. події — це послідовність подій, про які потрібно повідомити. Підтримуваними подіями є рядки "start", "end", "comment", "pi", "start-ns" і "end-ns" (події «ns» використовуються для отримання детальної інформації про простір імен). Якщо events опущено, повідомляються лише події "end".

feed(data)

Передайте надані дані в байтах аналізатору.

flush()

Triggers parsing of any previously fed unparsed data, which can be used to ensure more immediate feedback, in particular with Expat >=2.6.0. The implementation of flush() temporarily disables reparse deferral with Expat (if currently enabled) and triggers a reparse. Disabling reparse deferral has security consequences; please see xml.parsers.expat.xmlparser.SetReparseDeferralEnabled() for details.

Note that flush() has been backported to some prior releases of CPython as a security fix. Check for availability of flush() using hasattr() if used in code running across a variety of Python versions.

Added in version 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 на той момент не визначено . Те саме стосується елемента діти; вони можуть бути або не бути присутніми.

Якщо вам потрібен повністю заповнений елемент, шукайте події «кінець».

Added in version 3.4.

Змінено в версії 3.8: Додано події comment і pi.

Винятки

class xml.etree.ElementTree.ParseError

Помилка аналізу XML, викликана різними методами аналізу в цьому модулі, коли аналіз не вдається. Рядкове представлення екземпляра цього винятку міститиме зручне повідомлення про помилку. Крім того, він матиме такі доступні атрибути:

code

Числовий код помилки від аналізатора expat. Перегляньте документацію xml.parsers.expat, щоб переглянути список кодів помилок та їх значення.

position

Кортеж чисел рядка, стовпця, що вказує, де сталася помилка.

Виноски