Работа с XML из Python
Не все элементы входных данных XML будут в конечном итоге являться элементами анализируемого дерева. В настоящий момент этот модуль пропускает все комментарии XML, инструкции по обработке и объявления типа документа во входных данных. Тем не менее, деревья, построенные с использованием API этого модуля, а не синтаксического анализа из XML-текста, могут иметь комментарии и инструкции по обработке в них.
Создание и сборка XML-документов
Импорт модуля Элемента Дерева
import xml.etree.ElementTree as ET
Функция Element () используется для создания элементов XML
p=ET.Element('parent')
Функция SubElement (), используемая для создания вложенных элементов в элементе give
c = ET.SubElement(p, 'child1')
Функция dump() используется для вывода элементов xml .
ET.dump(p) #
Если вы хотите сохранить в файл, создайте дерево XML с функцией ElementTree() и сохраните в файл, используя метод write()
tree = ET.ElementTree(p) tree.write("sample.xml")
Функция Comment() используется для вставки комментариев в XML-файл.
comment = ET.Comment('user comment') p.append(comment) #этот комментарий будет добавлен к родительскому элементу ET.dump(p) #
Изменение файла XML
Импортируйте модуль ElementTree и откройте файл XML, получите элемент XML
import xml.etree.ElementTree as ET tree = ET.parse('sample.xml') root=tree.getroot() element = root[0] #получите первого ребенка родительского корня element #
Элементом объекта можно управлять, изменяя его поля, добавляя и изменяя атрибуты, добавляя и удаляя дочерние элементы
element.set('attribute_name', 'attribute_value') #установите артрибут xml элементу element.text="string_text"
Если вы хотите удалить элемент, используйте метод Element.remove()
root.remove(element)
Метод ElementTree.write() , используемый для вывода объекта XML в файлы XML.
tree.write('sample.xml')
Открытие и чтение больших файлов XML с помощью iterparse (инкрементальный анализ)
Иногда мы не хотим загружать весь XML-файл, чтобы получить необходимую нам информацию. В этих случаях полезно постепенно загружать соответствующие разделы и затем удалять их, когда мы закончим. С помощью функции iterparse вы можете редактировать дерево элементов, которое хранится при разборе XML.
Импортируйте объект ElementTree:
import xml.etree.ElementTree as ET
Откройте файл .xml и переберите все элементы:
for event, elem in ET.iterparse("yourXMLfile.xml"): # . сделайте что-нибудь .
Кроме того, мы можем искать только определенные события, такие как начальный / конечный теги или пространства имен. Если эта опция не указана (как указано выше), возвращаются только события «end»:
events=("start", "end", "start-ns", "end-ns") for event, elem in ET.iterparse("yourXMLfile.xml", events=events): # . сделайте что-нибудь .
Вот полный пример, показывающий, как очистить элементы из дерева в памяти, когда мы закончим с ними:
for event, elem in ET.iterparse("yourXMLfile.xml", events=("start","end")): if elem.tag == "record_tag" and event == "end": print elem.text elem.clear() # . сделайтe что-нибудь другое .
Открытие и чтение с помощью ElementTree
Импортируйте объект ElementTree, откройте соответствующий XML-файл и получите корневой тег:
import xml.etree.ElementTree as ET tree = ET.parse("yourXMLfile.xml") root = tree.getroot()
Есть несколько способов поиска по дереву. Сначала по итерации:
for child in root: print(child.tag, child.attrib)
В противном случае вы можете ссылаться на определенные места, такие как список:
print(root[0][1].text)
Для поиска конкретных тегов по имени, используйте .find или .findall :
print(root.findall("myTag")) print(root[0].find("myOtherTag"))
Поиск в XML с помощью XPath
Начиная с версии 2.7 ElementTree имеет лучшую поддержку XPath запросов. XPath — это синтаксис, позволяющий вам перемещаться по XML, как SQL используется для поиска в базе данных. Как find и findall функции поддержки XPath. Xml ниже будет использоваться для этого примера
Мечтают ли андроиды об электроовцах? Philip K. Dick The Colour of Magic Terry Pratchett The Eye of The World Robert Jordan
Поиск всех книг:
import xml.etree.cElementTree as ET tree = ET.parse('sample.xml') tree.findall('Books/Book')
Поиск книги с названием «Цвет магии»:
tree.find("Books/Book[Title='The Colour of Magic']") # всегда используйте '' в правой стороне сравнения
tree.find("Books/Book[@id='5']") # поиск с xml атрибутами должен иметь '@' перед именем
Поиск второй книги:
tree.find("Books/Book[2]") # индексы начинаются с 1, не с 0
Поиск последней книги:
tree.find("Books/Book[last()]") # 'last' единственная xpath функция позволенная в ElementTree
Поиск всех авторов:
tree.findall(".//Author") # поиск с // должен использовать родственный путь
Как распарсить xml python?
Здравствуйте!
Ребята, подскажите, каким образом можно корректно распарить xml документ при помощи PYTHON?
Только начинаю, и не могу найти хорошего примера.
Хотелось бы разобраться на практике с комментариями.
Вот мой документ — defaultVar.xml
Host 10.64.13.131:1576 true false String 1559628965605 MaxConnections 10 true false Integer 1559628965605 SID taffy true false String 1559628965605
Может ли кто-то показать, каким образом выбирать тэги SID, HOST (а так же все их атрибуты!).
Совсем не доходит голова. Если можно, то с комментариями.
Спасибо!
- Вопрос задан более трёх лет назад
- 3965 просмотров
1 комментарий
Простой 1 комментарий
Как парсить xml python
Argument ‘Topic id’ is null or empty
Сейчас на форуме
© Николай Павлов, Planetaexcel, 2006-2023
info@planetaexcel.ru
Использование любых материалов сайта допускается строго с указанием прямой ссылки на источник, упоминанием названия сайта, имени автора и неизменности исходного текста и иллюстраций.
ООО «Планета Эксел» ИНН 7735603520 ОГРН 1147746834949 | ИП Павлов Николай Владимирович ИНН 633015842586 ОГРНИП 310633031600071 |
xml.etree.ElementTree — ElementTree XML API
Модуль xml.etree.ElementTree реализует простой и эффективный API для анализа и создания XML-данных.
Изменено в версии 3.3: Модуль будет использовать быструю реализацию, когда это возможно. Модуль xml.etree.cElementTree устарел.
Модуль xml.etree.ElementTree не защищен от злонамеренно созданных данных. Если вам нужно распарсить ненадежные или неаутентифицированные данные, см. Уязвимости XML .
Руководство
Краткое руководство по использованию xml.etree.ElementTree (коротко — ET ). Цель состоит в том, чтобы продемонстрировать некоторые строительные блоки и основные концепции модуля.
XML-дерево и элементы
XML по своей сути является иерархическим форматом данных, и наиболее естественным способом его представления является дерево. Для этой цели у ET есть два класса — ElementTree представляет весь XML-документ в виде дерева, а Element представляет отдельный узел в этом дереве. Взаимодействие со всем документом (чтение и запись в/из файлов) обычно осуществляется на уровне ElementTree . Взаимодействие с одним элементом XML и его подэлементами осуществляется на уровне Element .
Разбор XML
Мы будем использовать следующий XML-документ в качестве образца данных для данного раздела:
name="Liechtenstein"> 1 2008 141100 name="Austria" direction="E"/> name="Switzerland" direction="W"/> name="Singapore"> 4 2011 59900 name="Malaysia" direction="N"/> name="Panama"> 68 2011 13600 name="Costa Rica" direction="W"/> name="Colombia" direction="E"/>
Мы можем импортировать данные, прочитав их из файла:
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 country country
Дочерние элементы вложены, и мы можем получить доступ к определенным дочерним узлам по индексу:
>>> root[0][1].text '2008'
Не все элементы входных XML-данных окажутся элементами анализируемого дерева. В настоящее время модуль пропускает любые XML-комментарии, инструкции по обработке и объявления типов документов во входных данных. Тем не менее, деревья, построенные с использованием API модуля, а не парсинга текста XML, могут содержать комментарии и инструкции по обработке; они будут включены при генерации XML вывода. Доступ к объявлению типа документа можно получить, передав пользовательский экземпляр TreeBuilder конструктору XMLParser .
Pull API для неблокирующего парсинга
Для большинства функций парсинга в этом модуле требуется, чтобы весь документ был прочитан сразу, прежде чем возвращать какой-либо результат. Можно использовать XMLParser и вводить в него данные постепенно, но это push API, который вызывает методы для цели обратного вызова, что слишком низкоуровнево и неудобно для большинства нужд. Иногда пользователю действительно нужна возможность парсинга XML поэтапно, без блокировки операций, при этом наслаждаясь удобством полностью сконструированных объектов Element .
Самый мощный инструмент для этого использовать XMLPullParser . Он не требует блокирующего чтения для получения XML данных, а вместо этого получает данные постепенно с вызовами XMLPullParser.feed() . Чтобы получить распарсенные элементы XML, вызовите XMLPullParser.read_events() . Пример:
>>> parser = ET.XMLPullParser(['start', 'end']) >>> parser.feed('sometext' ) >>> list(parser.read_events()) [('start', )] >>> parser.feed(' more text') >>> for event, elem in parser.read_events(): . print(event) . print(elem.tag, 'text=', elem.text) . end
Очевидный вариант использования — приложения, которые работают в неблокирующем режиме, когда XML-данные принимаются из сокета или считываются постепенно с какого-либо устройства хранения. В таких случаях блокирование чтения недопустимо.
Из-за своей гибкости XMLPullParser может быть неудобным для более простых случаев использования. Если вы не возражаете против того, чтобы ваше приложение блокировало чтение XML-данных, но все же вам нужны возможности инкрементного парсинга, взгляните на iterparse() . Может пригодиться, когда вы читаете большой XML-документ и не хотите держать его полностью в памяти.
Поиск интересующих элементов
У Element есть несколько полезных методов, которые помогают рекурсивно перебирать всё поддерево под ним (его дочерние элементы, их дочерние элементы и т. д.). Например, Element.iter() :
>>> for neighbor in root.iter(‘neighbor’): . print(neighbor.attrib) .
Element.findall() находит только элементы с тегом, которые являются прямыми дочерними элементами текущего элемента. Element.find() находит первый дочерний элемент с определённым тегом, а Element.text получает доступ к текстовому содержимому элемента. Element.get() обращается к атрибутам элемента:
>>> for country in root.findall('country'): . rank = country.find('rank').text . name = country.get('name') . print(name, rank) . Liechtenstein 1 Singapore 4 Panama 68
Более сложное определение поиска элементов, возможно с помощью XPath .
Изменение XML файла
ElementTree предоставляет простой способ создания XML-документов и записи их в файлы. Этой цели служит метод ElementTree.write() .
После создания объектом Element можно управлять, напрямую изменяя его поля (например, Element.text ), добавляя и изменяя атрибуты (метод Element.set() ), а также добавляя новых дочерних элементов (например, с помощью Element.append() ).
Допустим, мы хотим прибавить единицу к рангу каждой страны, а также добавить атрибут updated к элементу ранга:
>>> for rank in root.iter('rank'): . new_rank = int(rank.text) + 1 . rank.text = str(new_rank) . rank.set('updated', 'yes') . >>> tree.write('output.xml')
Теперь наш XML выглядит так:
name="Liechtenstein"> updated="yes">2 2008 141100 name="Austria" direction="E"/> name="Switzerland" direction="W"/> name="Singapore"> updated="yes">5 2011 59900 name="Malaysia" direction="N"/> name="Panama"> updated="yes">69 2011 13600 name="Costa Rica" direction="W"/> name="Colombia" direction="E"/>
Мы можем удалить элементы, используя Element.remove() . Допустим, мы хотим удалить все страны с рейтингом выше 50:
>>> for country in root.findall('country'): . # использование root.findall(), чтобы избежать удаления во время обхода . rank = int(country.find('rank').text) . if rank > 50: . root.remove(country) . >>> tree.write('output.xml')
Обратите внимание, что одновременное изменение во время итерации может привести к проблемам, как и при повторении и изменении списков или словарей Python. Поэтому в примере сначала собираются все совпадающие элементы с root.findall() , и только затем выполняется итерация по списку совпадений.
Теперь наш XML выглядит так:
name="Liechtenstein"> updated="yes">2 2008 141100 name="Austria" direction="E"/> name="Switzerland" direction="W"/> name="Singapore"> updated="yes">5 2011 59900 name="Malaysia" direction="N"/>
Создание XML-документов
Функция SubElement() также предоставляет удобный способ создания новых подэлементов для данного элемента:
>>> a = ET.Element('a') >>> b = ET.SubElement(a, 'b') >>> c = ET.SubElement(a, 'c') >>> d = ET.SubElement(c, 'd') >>> ET.dump(a)
Разбор XML с пространствами имён
Если у XML есть пространства имён, теги и атрибуты с префиксами в форме prefix:sometag расширяются до sometag , где prefix заменяется полным URI. Кроме того, если есть пространство имён по умолчанию, данный полный URI будет добавлен ко всем тегам без префикса.
Вот пример XML, который включает два пространства имён, одно с префиксом «fictional», а другое служит пространством имён по умолчанию:
xmlns:fictional="http://characters.example.com" xmlns="http://people.example.com"> John Cleese Lancelot Archie Leach Eric Idle Sir Robin Gunther Commander Clement
Один из способов поиска и изучения этого примера XML — вручную добавить URI к каждому тегу или атрибуту в xpath find() или findall() :
root = fromstring(xml_text) for actor in root.findall('actor'): name = actor.find('name') print(name.text) for char in actor.findall('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 из раздела Парсинг XML :
import xml.etree.ElementTree as ET root = ET.fromstring(countrydata) # Элементы верхнего уровня root.findall(".") # Все "neighbor" дети "country" детей элементов высшего уровня root.findall("./country/neighbor") # Узлы с name='Singapore', содержащий дочерний 'year' root.findall(".//year/..[@name='Singapore']") # 'year' узлы, которые являются дочерними узлами узлов с name='Singapore' root.findall(".//*[@name='Singapore']/year") # Все "соседние" узлы, которые являются вторым нижестоящим элементом их родителя root.findall(".//neighbor[2]")
Для XML с пространствами имён использовать обычную квалифицированную нотацию tag :
# Все дубликатные теги "title" в документе root.findall(".//title")
Поддерживаемый синтаксис XPath
Выбирает все дочерние элементы с заданным тегом. Например, spam выбирает все дочерние элементы с именем spam , а spam/egg выбирает всех внуков с именем egg во всех потомках с именем spam . * выбирает все теги в данном пространстве имён, <*>spam выбирает теги с именем spam в любом пространстве имён (или нет), а <>* выбирает только теги, которые не находятся в пространстве имён.
Изменено в версии 3.8: Добавлена поддержка подстановочных знаков звездочки.
Выбирает все элементы, полное текстовое содержимое которых, включая потомков, равного заданному text .
Добавлено в версии 3.7.
Предикатам (выражениям в квадратных скобках) должно предшествовать имя тега, звездочка или другой предикат. Предикатам position должно предшествовать имя тега.
Справка
Функции
xml.etree.ElementTree. canonicalize ( xml_data=None, *, out=None, from_file=None, **options )
Канонизация — способ нормализации вывода XML таким образом, чтобы было возможно побайтовое сравнение и цифровые подписи. Это уменьшило свободу, которая есть у XML сериализаторов, и вместо этого генерирует более ограниченное представление XML. Основные ограничения касаются размещения объявлений пространств имён, порядка атрибутов и игнорируемых пробелов.
Функция принимает строку данных XML (xml_data) или путь к файлу или объект, подобный файлу (from_file) в качестве входных данных, преобразует их в каноническую форму и записывает их, используя out файл(-подобный) объект, если он предоставлен, или в противном случае возвращает его как текстовую строку. В выходной файл поступает текст, а не байты. Поэтому его следует открывать в текстовом режиме с кодировкой utf-8 .
xml_data = ". " print(canonicalize(xml_data)) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(xml_data, out=out_file) with open("c14n_output.xml", mode='w', encoding='utf-8') as out_file: canonicalize(from_file="inputfile.xml", out=out_file)
Конфигурация options выглядит следующим образом:
- with_comments: установить значение true, чтобы включать комментарии (по умолчанию: false)
- strip_text: установить значение true, чтобы удалить пробелы до и после текстового содержимого (по умолчанию: false)
- rewrite_prefixes: установить значение true, чтобы заменить префиксы пространства имён на «n» (по умолчанию: false)
- qname_aware_tags: множество имён тегов, поддерживающих qname, в которых префиксы должны заменяться текстовым содержимом (по умолчанию: пусто)
- qname_aware_attrs: множество имён атрибутов, поддерживающих qname, в которых префиксы должны заменяться текстовым содержимом (по умолчанию: пусто)
- exclude_attrs: множество имён атрибутов, которые не следует сериализовать
- exclude_tags: множество имён тегов, которые не следует сериализовать
В приведенном выше списке опций «набор» относится к любой коллекции или итерации строк, упорядочение не ожидается.
Добавлено в версии 3.8.
xml.etree.ElementTree. Comment ( text=None )
Фабрика элементов комментария. Функция фабрика создаёт специальный элемент, который будет сериализован как XML-комментарий стандартным сериализатором. Строка комментария может быть строкой байтов или Юникод строкой. text — строка, содержащая строку комментария. Возвращает экземпляр элемента, представляющий комментарий.
Обратите внимание, что XMLParser пропускает комментарии во входных данных вместо того, чтобы создавать для них объекты комментариев. ElementTree будет содержать узлы комментариев, только если они были вставлены в дерево с помощью одного из методов Element .
xml.etree.ElementTree. dump ( elem )
Записывает дерево элементов или структуру элементов в sys.stdout. Функция должна использоваться только для отладки.
Точный формат вывода зависит от реализации. В данной версии он записывается как обычный XML-файл.
elem — дерево элементов или отдельный элемент.
Изменено в версии 3.8: Функция dump() теперь сохраняет порядок атрибутов, указанный пользователем.
xml.etree.ElementTree. fromstring ( text, parser=None )
Парсит XML-раздел из строковой константы. То же, что и XML() . text — строка, содержащая XML данные. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . Возвращает экземпляр Element .
xml.etree.ElementTree. fromstringlist ( sequence, parser=None )
Парсит XML-документ из последовательности строковых фрагментов. sequence — список или другая последовательность, содержащая фрагменты данных XML. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . Возвращает экземпляр Element .
Добавлено в версии 3.2.
xml.etree.ElementTree. iselement ( element )
Проверить, является ли объект допустимым объектом-элементом. element — экземпляр элемента. Вернуть True , если это объект элемента.
xml.etree.ElementTree. iterparse ( source, events=None, parser=None )
Инкрементально парсит XML-раздел в дереве элементов и сообщает пользователю о происходящем. source — имя файла или файловый объект , содержащий XML данные. events — последовательность событий, о которых нужно сообщить. Поддерживаемые события — строки «start» , «end» , «comment» , «pi» , «start-ns» и «end-ns» (события «ns» используются для получения подробной информации о пространстве имён). Если events пропущен, сообщается только о событиях «end» . parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . parser является подклассом XMLParser и может использовать только TreeBuilder по умолчанию в качестве цели. Возвращает итератор , предоставляя пары (event, elem) .
Обратите внимание, что, хотя iterparse() строит дерево постепенно, он выдает блокирующее чтение для source (или файла, который он называет). Таким образом, он не подходит для приложений, в которых невозможно выполнить блокирующее чтение. Для полностью неблокирующего парсинга см. XMLPullParser .
iterparse() гарантирует только то, что он видел символ «>» начального тега, когда он испускает событие «start», поэтому атрибуты определены, но содержимое атрибутов text и tail в этой точке не определено. То же самое относится к дочерним элементам; они могут присутствовать, а могут и не присутствовать.
Если вам нужен полностью заполненный элемент, ищите вместо этого «конечные» события.
Не рекомендуется, начиная с версии 3.4: Аргумент parser.
Изменено в версии 3.8: Добавлены события comment и pi .
xml.etree.ElementTree. parse ( source, parser=None )
Парсит XML-раздел в дереве элементов. source — имя файла или объект файла, содержащий XML данные. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . Возвращает экземпляр ElementTree .
xml.etree.ElementTree. ProcessingInstruction ( target, text=None )
Фабрика PI элементов. Функция фабрика создаёт специальный элемент, который будет сериализован как оператор обработки XML. target — строка, содержащая цель PI. text — строка, содержащая содержимое PI, если указано. Возвращает экземпляр элемента, представляющий инструкцию обработки.
Обратите внимание, что XMLParser пропускает инструкции обработки во входных данных вместо создания для них объектов комментариев. ElementTree будет содержать узлы инструкций обработки, только если они были вставлены в дерево с помощью одного из методов Element .
xml.etree.ElementTree. register_namespace ( prefix, uri )
Регистрирует префикс пространства имён. Реестр является глобальным, и любое существующее сопоставление для данного префикса или URI пространства имён будет удалено. prefix — префикс пространства имён. uri — uri пространства имён. Теги и атрибуты в этом пространстве имён будут сериализованы с заданным префиксом, если это вообще возможно.
Добавлено в версии 3.2.
xml.etree.ElementTree. SubElement ( parent, tag, attrib=<>, **extra )
Фабрика субэлемента. Функция создаёт экземпляр элемента и добавляет его к существующему элементу.
Имя элемента, имена атрибутов и значения атрибутов могут быть строками байтов или Юникод строками. parent — родительский элемент. tag — имя подэлемента. attrib — необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные как ключевые аргументы. Возвращает экземпляр элемента.
xml.etree.ElementTree. tostring ( element, encoding=»us-ascii», method=»xml», *, xml_declaration=None, default_namespace=None, short_empty_elements=True )
Создаёт строковое представление элемента XML, включая все подэлементы. element — экземпляр Element . encoding [1] — кодировка вывода (по умолчанию US-ASCII). Используйте encoding=»unicode» для создания строки Юникод (в противном случае создаётся строка байтов). method — «xml» , «html» или «text» (по умолчанию «xml» ). У xml_declaration, default_namespace и short_empty_elements то же значение, что и в ElementTree.write() . Возвращает (необязательно) закодированную строку, содержащую XML данные.
Добавлено в версии 3.4: Параметр short_empty_elements.
Добавлено в версии 3.8: Параметры xml_declaration и default_namespace.
Изменено в версии 3.8: Функция tostring() теперь сохраняет порядок атрибутов, указанный пользователем.
xml.etree.ElementTree. tostringlist ( element, encoding=»us-ascii», method=»xml», *, xml_declaration=None, default_namespace=None, short_empty_elements=True )
Создаёт строковое представление элемента XML, включая все подэлементы. element — экземпляр Element . encoding [1] — кодировка вывода (по умолчанию US-ASCII). Используйте encoding=»unicode» для создания Юникод строки (в противном случае создаётся строка байтов). method — «xml» , «html» или «text» (по умолчанию «xml» ). У xml_declaration, default_namespace и short_empty_elements то же значение, что и в ElementTree.write() . Возвращает список (необязательно) закодированных строк, содержащих XML данные. Он не гарантирует какой-либо последовательности, кроме b»».join(tostringlist(element)) == tostring(element) .
Добавлено в версии 3.2.
Добавлено в версии 3.4: Параметр short_empty_elements.
Добавлено в версии 3.8: Параметры xml_declaration и default_namespace.
Изменено в версии 3.8: Функция tostringlist() теперь сохраняет порядок атрибутов, указанный пользователем.
xml.etree.ElementTree. XML ( text, parser=None )
Парсит XML-раздел из строковой константы. Функция может использоваться для встраивания «XML-литералов» в код Python. text — строка, содержащая XML данные. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . Возвращает экземпляр Element .
xml.etree.ElementTree. XMLID ( text, parser=None )
Парсит раздел XML из строковой константы, а также возвращает словарь, который сопоставляет элемент id:s с элементами. text — строка, содержащая XML данные. parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . Возвращает кортеж, содержащий экземпляр Element и словарь.
Поддержка XInclude
Модуль обеспечивает ограниченную поддержку директивы XInclude через вспомогательный модуль xml.etree.ElementInclude . Модуль можно использовать для вставки поддеревьев и текстовых строк в деревья элементов на основе информации в дереве.
Пример
Далее пример, демонстрирующий использование модуля XInclude. Чтобы подключить XML-документ в текущий документ, используйте элемент include и установите атрибут parse «xml» и href, чтобы указать документ, который нужно подключить.
xmlns:xi="http://www.w3.org/2001/XInclude"> href="source.xml" parse="xml" />
По умолчанию атрибут href рассматривается как имя файла. Вы можете использовать собственные загрузчики, чтобы переопределить это поведение. Также обратите внимание, что стандартный помощник не поддерживает синтаксис XPointer.
Чтобы обработать файл, загрузить его как обычно и передайте корневой элемент модулю xml.etree.ElementTree :
from xml.etree import ElementTree, ElementInclude tree = ElementTree.parse("document.xml") root = tree.getroot() ElementInclude.include(root)
Модуль ElementInclude заменяет элемент include корневым элементом из документа source.xml. Результат может выглядеть примерно так:
xmlns:xi="http://www.w3.org/2001/XInclude"> This is a paragraph.
Если атрибут parse пропущен, по умолчанию используется «xml». Атрибут href обязателен.
Чтобы включить текстовый документ, использовать элемент include и установить для атрибута parse значение «text»:
xmlns:xi="http://www.w3.org/2001/XInclude"> Copyright (c) href="year.txt" parse="text" />.
Результат может выглядеть примерно так:
xmlns:xi="http://www.w3.org/2001/XInclude"> Copyright (c) 2003.
Справка
Функции
xml.etree.ElementInclude. default_loader ( href, parse, encoding=None )
Загрузчик по умолчанию. Загрузчик по умолчанию считывает включенный ресурс с диска. href — URL-адрес. parse предназначен для режима парсинга «xml» или «text». encoding — дополнительная кодировка текста. Если не указано, кодировка — utf-8 . Возвращает расширенный ресурс. Если режим парсинга — «xml» , это экземпляр ElementTree. Если режим парсинга — «текст», это строка Юникод. Если загрузчик не работает, он может вернуть None или вызвать исключение.
xml.etree.ElementInclude. include ( elem, loader=None )
Функция расширяет директивы XInclude. elem — корневой элемент. loader — дополнительный загрузчик ресурсов. Если пропущен, по умолчанию используется default_loader() . Если задан, то должен быть вызываемый объект, реализующий тот же интерфейс, что и default_loader() . Возвращает расширенный ресурс. Если режим парсинга — «xml» , то экземпляр ElementTree. Если режим парсинга — «text», то Юникод строка. Если загрузчик не работает, он может вернуть None или вызвать исключение.
Элементные объекты
class xml.etree.ElementTree. Element ( tag, attrib=<>, **extra )
Элементный класс. Класс определяет интерфейс Element и предоставляет эталонную реализацию этого интерфейса.
Имя элемента, имена атрибутов и значения атрибутов могут быть строками байтов или строками Юникод. tag — имя элемента. attrib — необязательный словарь, содержащий атрибуты элемента. extra содержит дополнительные атрибуты, заданные как ключевые аргументы.
Строка, определяющая, какие данные представляет этот элемент (другими словами, тип элемента).
Атрибуты могут использоваться для хранения дополнительных данных, связанных с элементом. Их значения обычно являются строками, но могут быть любыми объектами, зависящими от приложения. Если элемент создан из файла XML, атрибут text содержит либо текст между начальным тегом элемента и его первым дочерним или конечным тегом, либо None , а атрибут tail содержит текст между конечным тегом элемента и следующим тегом. , или None . Для XML данных.
у элемента a есть None и для text и для tail атрибутов, у элемента b есть text «1» и tail «4» , у элемента c есть text «2» и tail None , и у элемента d есть text None и tail «3» .
Чтобы собрать внутренний текст элемента, см. itertext() , например «».join(element.itertext()) .
Приложения могут хранить в этих атрибутах произвольные объекты.
Словарь, содержащий атрибуты элемента. Обратите внимание, что хотя значение attrib всегда является настоящим изменяемым словарём Python, реализация ElementTree может выбрать использование другого внутреннего представления и создать словарь, только если кто-то об этом попросит. Чтобы воспользоваться преимуществами таких реализаций, по возможности использовать приведенные ниже словарные методы.
Следующие методы, подобные словарю, работают с атрибутами элемента.
Сбрасывает элемент. Функция удаляет все подэлементы, очищает все атрибуты и устанавливает атрибуты текста и хвоста на None .
Получает атрибут элемента с именем key.
Возвращает значение атрибута или default, если атрибут не был найден.
Возвращает атрибуты элемента в виде последовательности пар (имя, значение). Атрибуты возвращаются в произвольном порядке.
Возвращает имена атрибутов элементов в виде списка. Имена возвращаются в произвольном порядке.
Установить для атрибута key элемент value.
Следующие методы работают с дочерними элементами (подэлементами) элемента.
Добавляет элемент subelement в конец внутреннего списка подэлементов элемента. Вызывает TypeError , если subelement не Element .
Добавляет subelements из объекта последовательности с нулевым или более элементами. Вызывает TypeError , если подэлемент не является Element .
Добавлено в версии 3.2.
find ( match, namespaces=None )
Находит первый подэлемент, соответствующий match. match может быть именем тега или путь . Возвращает экземпляр элемента или None . namespaces — необязательное отображение префикса пространства имён на полное имя. Передайте » в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в заданное пространство имён.
findall ( match, namespaces=None )
Находит все совпадающие подэлементы по имени тега или путь . Возвращает список, содержащий все совпадающие элементы в порядке документа. namespaces — необязательное отображение префикса пространства имён на полное имя. Передайте » в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в заданное пространство имён.
findtext ( match, default=None, namespaces=None )
Находит текст для первого подэлемента, соответствующего match. match может быть именем тега или путём . Возвращает текстовое содержимое первого совпадающего элемента или default, если элемент не найден. Обратите внимание, что если у соответствующего элемента нет текстового содержимого, возвращается пустая строка. namespaces — необязательное отображение префикса пространства имён на полное имя. Передайте » в качестве префикса, чтобы переместить все имена тегов без префикса в выражении в заданное пространство имён.
Устарело с версии 3.2, будет удалено в 3.9 версии.: Используйте list(elem) или итерацию.
getiterator ( tag=None )
Устарело с версии 3.2, будет удалено в 3.9 версии.: Вместо него используйте метод Element.iter() .
insert ( index, subelement )
Вставляет subelement в указанную позицию в данном элементе. Вызывает TypeError , если subelement не Element .
Создаёт итерируемое дерево с текущим элементом в качестве корня. Итератор выполняет итерацию по этому элементу и всем элементам под ним в порядке документа (сначала в глубину). Если tag не None или ‘*’ , от итератора возвращаются только элементы, тег которых равен tag. Если структура дерева изменяется во время итерации, результат не определен.
Добавлено в версии 3.2.
iterfind ( match, namespaces=None )
Находит все совпадающие подэлементы по имени тега или пути . Возвращает итерируемый объект, отдающий все совпадающие элементы в порядке документа. namespaces — необязательное отображение префикса пространства имён на полное имя.
Добавлено в версии 3.2.
Создаёт текстовый итератор. Итератор перебирает этот элемент и все подэлементы в порядке документа и возвращает весь внутренний текст.
Добавлено в версии 3.2.
makeelement ( tag, attrib )
Создаёт новый объект-элемент того же типа, что и этот элемент. Не вызывайте этот метод, использовать вместо него заводскую функцию SubElement() .
Удаляет subelement из элемента. В отличие от методов find* метод сравнивает элементы на основе идентификатора экземпляра, а не значения или содержимого тега.
Объекты Element также поддерживают следующие методы типа последовательности для работы с подэлементами: __delitem__() , __getitem__() , __setitem__() , __len__() .
Внимание! Элементы без подэлементов будут тестироваться как False . Поведение изменится в будущих версиях. Вместо него используйте специальный тест len(elem) или elem is None .
element = root.find('foo') if not element: # осторожно! print("element not found, or element has no subelements") if element is None: print("element not found")
До Python 3.8 порядок сериализации XML-атрибутов элементов был искусственно предсказуем путём сортировки атрибутов по их имени. Основываясь теперь на гарантированном порядке словарей, данное произвольное переупорядочение было удалено в Python 3.8, чтобы сохранить порядок, в котором атрибуты были первоначально проанализированы или созданы пользовательским кодом.
В общем, код пользователя должен стараться не зависеть от определенного порядка атрибутов, учитывая, что Набор информации XML явно исключает порядок атрибутов из передачи информации. Код должен быть готов к работе с любым упорядочиванием при вводе. В случаях, когда требуется детерминированный вывод XML, например для криптографической подписи или наборов тестовых данных каноническая сериализация доступна с помощью функции canonicalize() .
В случаях, когда канонический вывод неприменим, но определенный порядок атрибутов всё ещё желателен при выводе, код должен стремиться к созданию атрибутов непосредственно в желаемом порядке, чтобы избежать несоответствия восприятия для читателей кода. В случаях, когда этого трудно достичь, перед сериализацией можно применить следующий рецепт, чтобы обеспечить выполнение порядка независимо от создания Element:
def reorder_attributes(root): for el in root.iter(): attrib = el.attrib if len(attrib) > 1: # отрегулировать порядок атрибутов, например путём сортировки attribs = sorted(attrib.items()) attrib.clear() attrib.update(attribs)
Объекты ElementTree
class xml.etree.ElementTree. ElementTree ( element=None, file=None )
Класс-оболочка ElementTree. Класс представляет всю иерархию элементов и добавляет некоторую дополнительную поддержку сериализации в стандартный XML и обратно.
element — корневой элемент. Дерево инициализируется содержимым XML file, если указан.
Заменяет корневой элемент данного дерева. Отбрасывает текущее содержимое дерева и заменяет его заданным элементом. Используйте с осторожностью. element — экземпляр элемента.
find ( match, namespaces=None )
То же, что и Element.find() , начиная с корня дерева.
findall ( match, namespaces=None )
То же, что и Element.findall() , начиная с корня дерева.
findtext ( match, default=None, namespaces=None )
То же, что и Element.findtext() , начиная с корня дерева.
Устарело с версии 3.2, будет удалено в 3.9 версии.: Вместо этого используйте метод ElementTree.iter() .
Возвращает корневой элемент дерева.
Создаёт и возвращает итератор дерева для корневого элемента. Итератор перебирает все элементы в этом дереве в порядке секций. tag — тег, который нужно искать (по умолчанию возвращаются все элементы).
iterfind ( match, namespaces=None )
То же, что и Element.iterfind() , начиная с корня дерева.
Добавлено в версии 3.2.
parse ( source, parser=None )
Загружает внешний раздел XML в это дерево элементов. source — имя файла или файловый объект . parser — необязательный экземпляр парсера. Если не указан, используется стандартный парсер XMLParser . Возвращает корневой элемент раздела.
write ( file, encoding=»us-ascii», xml_declaration=None, default_namespace=None, method=»xml», *, short_empty_elements=True )
Записывает дерево элементов в файл формата XML. file — имя файла или файловый объект , открытый для записи. encoding [1] — кодировка вывода (по умолчанию US-ASCII). xml_declaration определяет, нужно ли добавлять в файл объявление XML. Никогда не используйте False , True всегда, None только для US-ASCII, UTF-8 или Юникод (по умолчанию None ). default_namespace устанавливает пространство имён XML по умолчанию (для «xmlns»). method — «xml» , «html» или «text» (по умолчанию «xml» ). Только ключевой параметр short_empty_elements, управляет форматированием элементов, не содержащих содержимого. Если True (по умолчанию), они выводятся как один самозакрывающийся тег, в противном случае они выводятся как пара начальных/конечных тегов.
Выходные данные могут быть строковыми ( str ) или двоичными ( bytes ). Контролируется аргументом encoding. Если encoding — «unicode» , вывод будет строкой; в противном случае он двоичный. Обратите внимание, что может конфликтовать с типом file, если открытый файловый объект ; убедитесь, что вы не пытаетесь записать строку в двоичный поток и наоборот.
Добавлено в версии 3.4: Параметр short_empty_elements.
Изменено в версии 3.8: Метод write() теперь сохраняет порядок атрибутов, указанный пользователем.
XML-файл, с которым будем работать:
html> head> title>Example pagetitle> head> body> p>Moved to a href="http://example.org/">example.orga> or a href="http://example.com/">example.coma>.p> body> html>
Пример изменения атрибута «target» каждой ссылки в первом абзаце:
>>> from xml.etree.ElementTree import ElementTree >>> tree = ElementTree() >>> tree.parse("index.xhtml") >>> p = tree.find("body/p") # Находит первое вхождение тега p в body >>> p >>> links = list(p.iter("a")) # Возвращает список всех ссылок >>> links [, ] >>> for i in 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 в форме local или, если задан аргумент тега, часть URI QName. Если задан tag, первый аргумент интерпретируется как URI, а этот аргумент интерпретируется как локальное имя. Экземпляры QName непрозрачны.
Объекты TreeBuilder
class xml.etree.ElementTree. TreeBuilder ( element_factory=None, *, comment_factory=None, pi_factory=None, insert_comments=False, insert_pis=False )
Конструктор универсальной элементной структуры. Конструктор преобразует последовательность вызовов методов start, data, end, comment и pi в правильно сформированную структуру элементов. Вы можете использовать этот класс для создания структуры элементов с помощью пользовательского парсера XML или парсера для какого-либо другого XML-подобного формата.
Если задан element_factory, должен быть вызываемым, принимающим два позиционных аргумента: тег и словарь атрибутов. Ожидается возвращение нового экземпляра элемента.
Если заданы функции comment_factory и pi_factory, должны вести себя как функции Comment() и ProcessingInstruction() для создания комментариев и инструкций по обработке. Если не указано, будут использоваться фабрики по умолчанию. Когда insert_comments и/или insert_pis истинны, комментарии/pis будут вставлены в дерево, если они появляются внутри корневого элемента (но не за его пределами).
Очищает буферы построителя и возвращает элемент документа верхнего уровня. Возвращает экземпляр Element .
Добавляет текст к текущему элементу. data — строка. Должна быть строка байтов или строка Юникод.
Закрывает текущий элемент. tag — имя элемента. Возвращает закрытый элемент.
Открывает новый элемент. tag — имя элемента. attrs — словарь, содержащий атрибуты элемента. Возвращает открытый элемент.
Создаёт комментарий с заданным text. Если insert_comments истинно, также добавит его в дерево.
Добавлено в версии 3.8.
pi ( target, text )
Создаёт комментарий с заданным именем target и text. Если insert_pis истинно, также добавит его в дерево.
Добавлено в версии 3.8.
Кроме того, пользовательский объект TreeBuilder может предоставлять следующие методы:
Обрабатывает объявление типа документа. name — имя типа документа. pubid — публичный идентификатор. system — системный идентификатор. Метод не существует в классе TreeBuilder по умолчанию.
Добавлено в версии 3.2.
start_ns ( prefix, uri )
Вызывается всякий раз, когда парсер встречает новое объявление пространства имён, перед обратным вызовом start() для открывающего элемента, который его определяет. prefix — » для пространства имён по умолчанию и объявленное имя префикса пространства имён в противном случае. uri — URI пространства имён.
Добавлено в версии 3.8.
end_ns ( prefix )
Вызывается после обратного вызова end() элемента, который объявил отображение префикса пространства имён, с именем prefix, вышедшее за пределы области видимости.
Добавлено в версии 3.8.
class xml.etree.ElementTree. C14NWriterTarget ( write, *, with_comments=False, strip_text=False, rewrite_prefixes=False, qname_aware_tags=None, qname_aware_attrs=None, exclude_attrs=None, exclude_tags=None )
Писатель C14N 2.0. Аргументы такие же, как для функции canonicalize() . Класс не строит дерево, а транслирует события обратного вызова непосредственно в сериализованную форму с помощью функции write.
Добавлено в версии 3.8.
Объекты XMLParser
class xml.etree.ElementTree. XMLParser ( *, target=None, encoding=None )
Класс является строительным блоком нижнего уровня модуля. Он использует xml.parsers.expat для эффективного анализа XML на основе событий. В него можно добавлять XML данные с приращением с помощью метода feed() , а события парсинга транслируются в push API путём вызова обратных вызовов для объекта target. Если target пропущен, используется стандартный TreeBuilder . Если задано encoding [1], значение переопределяет кодировку, указанную в файле XML.
Изменено в версии 3.8: Параметры теперь только ключевые . Аргумент html больше не поддерживается.
Завершает подачу данных в парсер. Возвращает результат вызова метода close() из target, переданного во время построения; по умолчанию это элемент документа верхнего уровня.
Отдаёт данные парсеру. data — закодированные данные.
XMLParser.feed() вызывает метод target start(tag, attrs_dict) для каждого открывающего тега, свой метод end(tag) для каждого закрывающего тега, а данные обрабатываются методом data(data) . Дополнительные поддерживаемые методы обратного вызова см. в классе TreeBuilder . XMLParser.close() вызывает метод target close() . XMLParser можно использовать не только для построения древовидной структуры. Далее пример подсчёта максимальной глубины XML-файла:
>>> from xml.etree.ElementTree import XMLParser >>> class MaxDepth: # Целевой объект парсера . maxDepth = 0 . depth = 0 . def start(self, tag, attrib): # Вызывается для каждого открывающего тега. . self.depth += 1 . if self.depth > self.maxDepth: . self.maxDepth = self.depth . def end(self, tag): # Вызывается для каждого закрывающего тега. . self.depth -= 1 . def data(self, data): . pass # Нам не нужно ничего делать с данными. . def close(self): # Вызывается после анализа всех данных. . return self.maxDepth . >>> target = MaxDepth() >>> parser = XMLParser(target=target) >>> exampleXml = """ . . . . . . . . . . """ >>> parser.feed(exampleXml) >>> parser.close() 4
Объекты XMLPullParser
class xml.etree.ElementTree. XMLPullParser ( events=None )
Парсер опрашивания, подходящий для неблокирующих приложений. Его API на стороне ввода аналогичен API XMLParser , но вместо того, чтобы отправлять вызовы цели обратного вызова, XMLPullParser собирает внутренний список событий парсинга и позволяет пользователю читать из него. events — последовательность событий, о которых необходимо сообщить. Поддерживаемые события — строки «start» , «end» , «comment» , «pi» , «start-ns» и «end-ns» (события «ns» используются для получения подробной информации о пространстве имён). Если events пропущен, сообщаются только «end» события.
Передать данные в байтах парсеру.
Сообщить парсеру, что поток данных завершён. В отличие от XMLParser.close() , метод всегда возвращает None . Любые события, которые ещё не получены при закрытии парсера, всё ещё могут быть прочитаны с помощью read_events() .
Вернуть итератор по событиям, которые были обнаружены в данных, переданных в парсер. Итератор отдаёт пары (event, elem) , где event — строка, представляющая тип события (например, «end» ), а elem — обнаруженный объект Element или другое значение контекста, как показано ниже.
- start , end : текущий элемент.
- comment , pi : текущий комментарий/оператор обработки
- start-ns : кортеж (prefix, uri) , называющий объявленное отображение пространства имён.
- end-ns : None (может измениться в будущей версии)
События, указанные в предыдущем вызове read_events() , не будут возвращены снова. События потребляются из внутренней очереди только тогда, когда они извлекаются из итератора, поэтому несколько считывателей, выполняющих итерацию параллельно через итераторы, полученные из read_events() , будут приводить к непредсказуемым результатам.
XMLPullParser гарантирует только то, что он видел символ «>» начального тега, когда он испускает событие «start», поэтому атрибуты определены, но содержимое атрибутов text и tail в этой точке не определено. То же самое относится к дочерним элементам; они могут присутствовать, а могут и отсутствовать.
Если вам нужен полностью заполненный элемент, ищите вместо него «end» события.
Добавлено в версии 3.4.
Изменено в версии 3.8: Добавлены события comment и pi .
Исключения
class xml.etree.ElementTree. ParseError
Ошибка парсинга XML, вызываемая различными методами парсинга в модуле при сбое парсинга. Строковое представление экземпляра исключения будет содержать удобное для пользователя сообщение об ошибке. Кроме того, для него будут доступны следующие атрибуты:
Числовой код ошибки expat парсера. См. документацию xml.parsers.expat для получения списка кодов ошибок и их значений.
Кортеж из чисел line, column, указывающих, где произошла ошибка.
[1] | (1, 2, 3, 4) Строка кодировки, включенная в вывод XML, должна соответствовать формату соответствующих стандартов. Например, «UTF-8» допустим, а «UTF8» нет. См. официальный сайт w3c и iana. |