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¶
Синтаксис |
Значення |
---|---|
|
Вибирає всі дочірні елементи з заданим тегом. Наприклад, Змінено в версії 3.8: Додано підтримку символів підстановки зірок. |
|
Вибирає всі дочірні елементи, включаючи коментарі та інструкції з обробки. Наприклад, |
|
Вибирає поточний вузол. Це здебільшого корисно на початку шляху, щоб вказати, що це відносний шлях. |
|
Вибирає всі піделементи на всіх рівнях під поточним елементом. Наприклад, |
|
Вибирає батьківський елемент. Повертає |
|
Вибирає всі елементи, які мають заданий атрибут. |
|
Вибирає всі елементи, для яких даний атрибут має задане значення. Значення не може містити лапки. |
|
Вибирає всі елементи, для яких даний атрибут не має заданого значення. Значення не може містити лапки. Added in version 3.10. |
|
Вибирає всі елементи, які мають дочірні елементи з іменем |
|
Вибирає всі елементи, повний текстовий вміст яких, включаючи нащадків, дорівнює заданому Added in version 3.7. |
|
Вибирає всі елементи, повний текстовий вміст яких, включно з нащадками, не відповідає заданому Added in version 3.10. |
|
Вибирає всі елементи, які мають дочірні елементи з назвою |
|
Вибирає всі елементи, які мають дочірні елементи з іменем Added in version 3.10. |
|
Вибирає всі елементи, які розташовані на заданій позиції. Позиція може бути цілим числом (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 standardXMLParser
parser is used. parser must be a subclass ofXMLParser
and can only use the defaultTreeBuilder
as a target. Returns an iterator providing(event, elem)
pairs; it has aroot
attribute that references the root element of the resulting XML tree once source is fully read. The iterator has theclose()
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. AnElementTree
will only contain processing instruction nodes if they have been inserted into to the tree using one of theElement
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 anElement
instance. If the parse mode is"text"
, this is a string. If the loader fails, it can returnNone
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 anElementTree
instance to find such element. loader is an optional resource loader. If omitted, it defaults todefault_loader()
. If given, it should be a callable that implements the same interface asdefault_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. PassNone
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"
і 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)¶
Appends subelements from an iterable of elements. Raises
TypeError
if a subelement is not anElement
.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 asTrue
regardless of whether subelements exist. Instead, prefer explicitlen(elem)
orelem 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 seexml.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 offlush()
usinghasattr()
if used in code running across a variety of Python versions.Added in version 3.13.
XMLParser.feed()
викликає метод targetstart(tag, attrs_dict)
для кожного початкового тегу, його методend(tag)
для кожного закриваючого тегу, і дані обробляються методомдані(дані)
. Інші підтримувані методи зворотного виклику див. у класіTreeBuilder
.XMLParser.close()
викликає метод targetclose()
.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 seexml.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 offlush()
usinghasattr()
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¶
Кортеж чисел рядка, стовпця, що вказує, де сталася помилка.
Виноски