Разбор XML в Python3
Что такое XML?
XML означает расширяемый язык разметки (eXtensible Markup LXtensible Markup Language), подмножество стандартного обобщённого языка разметки, и представляет собой язык разметки, используемый для разметки электронных файлов, чтобы они имели структуру. Вы можете узнать больше на этом сайтеУчебник по XML
XML был разработан для передачи и хранения данных.
XML — это набор правил для определения семантических тегов. Эти теги разделяют документ на множество частей и идентифицируют эти части.
Это также метаязык разметки, то есть синтаксический язык, используемый для определения других семантических структурированных языков разметки, относящихся к конкретным предметным областям.
Парсинг XML в Python
Распространённые интерфейсы программирования XML включают DOM и SAX. Эти два интерфейса обрабатывают XML-файлы по-разному, поэтому используются в разных ситуациях.
В Python есть три метода парсинга XML: ElementTree, SAX и DOM.
1. ElementTree
xml.etree.ElementTree — это модуль в стандартной библиотеке Python для работы с XML. Он предоставляет простой и эффективный API для разбора и генерации XML-документов.
2.SAX (простой API для XML)
Стандартная библиотека Python включает SAX-парсер. SAX использует событийную модель: обрабатывает XML-файлы, поочерёдно вызывая события и пользовательские функции обратного вызова во время разбора XML.
3.DOM (объектная модель документа)
Он разбирает XML-данные в дерево в памяти и работает с XML, манипулируя деревом.
Примеры XML-файлов, используемых в этой главеmovies.xmlСодержимое следующее:
Примеры
<movie title="Враг позади">
<type>Военный, триллер</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Разговор о войне между США и Японией</description>
</movie>
<movie title="Трансформеры">
<type>Аниме, научная фантастика</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>Научная фантастика</description>
</movie>
<movie title="Триган">
<type>Аниме, боевик</type>
<format>DVD</format>
<episodes>4</episodes>
<rating>PG</rating>
<stars>10</stars>
<description>Вэш Ураган!</description>
</movie>
<movie title="Иштар">
<type>Комедия</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Смотрибельная скука</description>
</movie>
</collection>
Python использует ElementTree для разбора XML
xml.etree.ElementTreeявляется модулем в стандартной библиотеке Python для работы с XML.
Ниже приведены некоторые ключевые концепции и примеры использования модуля xml.etree.ElementTree:
Объекты ElementTree и Element:
- ElementTree: Класс ElementTree — это древовидное представление XML-документа. Он содержит один или несколько объектов Element и представляет весь XML-документ.
- Element: Объект Element представляет элемент в XML-документе. Каждый элемент имеет тег, набор атрибутов и ноль или более дочерних элементов.
Разбор XML
метод fromstring(): Вы можете использовать метод fromstring() для преобразования строки, содержащей XML-данные, в объект Element:
Пример
xml_string = '<root><element>Some data</element></root>'
root = ET.fromstring(xml_string)
метод parse(): Если XML-данные хранятся в файле, вы можете использовать метод parse() для разбора всего XML-документа:
tree = ET.parse('example.xml')
root = tree.getroot()
Обход XML-дерева
метод find(): Используйте метод find() для поиска первого дочернего элемента с указанным тегом:
title_element = root.find('title')метод findall(): Используйте метод findall() для поиска всех дочерних элементов с указанным тегом:
book_elements = root.findall('book')
Доступ к атрибутам элемента и текстовому содержимому
attribАтрибут: Вы можете получить доступ к атрибутам элемента через атрибут attrib:
price = book_element.attrib['price']
textТекстовое содержимое: Вы можете получить доступ к текстовому содержимому элемента через атрибут text:
title_text = title_element.text
Создание XML
конструктор Element(): Используйте конструктор Element() для создания нового элемента:
new_element = ET.Element('new_element')Функция SubElement(): Используйте функцию SubElement() для создания дочернего элемента с указанным тегом:
new_sub_element = ET.SubElement(root, 'new_sub_element')
Изменение XML
Изменение атрибутов и текстового содержимого элемента: напрямую изменяйте атрибуты attrib и text элемента.
Удаление элемента: Вы можете удалить элемент с помощью метода remove():
root.remove(title_element)
Простое чтение XML-содержимого:
Пример
# Определите строку XML
xml_string = '''
<bookstore>
<book>
<title>Введение в Python</title>
<author>Джон Доу</author>
<price>29.99</price>
</book>
<book>
<title>Наука о данных с Python</title>
<author>Джейн Смит</author>
<price>39.95</price>
</book>
</bookstore>
'''
# Использовать ElementTree для разбора XML-строки
root = ET.fromstring(xml_string)
# Обойти XML-дерево
for book in root.findall('book'):
title = book.find('title').text
author = book.find('author').text
price = book.find('price').text
print(f'Название: {title}, Автор: {author}, Цена: {price}')
Вывод после выполнения приведённого выше кода:
Title: Introduction to Python, Author: John Doe, Price: 29.99 Title: Data Science with Python, Author: Jane Smith, Price: 39.95
Далее мы создадим XML-документ с информацией о книге, а затем воспользуемся этим модулем, чтобы разобрать и обработать его:
Пример
# Создать XML-документ
root = ET.Element('bookstore')
# Добавить первую книгу
book1 = ET.SubElement(root, 'book')
title1 = ET.SubElement(book1, 'title')
title1.text = 'Введение в Python'
author1 = ET.SubElement(book1, 'author')
author1.text = 'Джон Доу'
price1 = ET.SubElement(book1, 'price')
price1.text = '29.99'
# Добавить вторую книгу
book2 = ET.SubElement(root, 'book')
title2 = ET.SubElement(book2, 'title')
title2.text = 'Data Science with Python'
author2 = ET.SubElement(book2, 'author')
author2.text = 'Jane Smith'
price2 = ET.SubElement(book2, 'price')
price2.text = '39.95'
# Сохранить XML-документ в файл
tree = ET.ElementTree(root)
tree.write('books.xml')
# Разобрать XML-документ из файла
parsed_tree = ET.parse('books.xml')
parsed_root = parsed_tree.getroot()
# Обойти XML-дерево и вывести информацию о книге
for book in parsed_root.findall('book'):
title = book.find('title').text
author = book.find('author').text
price = book.find('price').text
print(f'Название: {title}, Автор: {author}, Цена: {price}')
В приведённом выше примере мы сначала создаём XML-документ, содержащий информацию о двух книгах. Затем мы сохраняем этот документ в файл books.xml. Далее мы используем метод ET.parse() для разбора XML-документа в файле, обходим дерево документа и извлекаем и выводим название, автора и цену каждой книги.
Python использует SAX для разбора XML
SAX — это событийно-ориентированный API.
Использование SAX для разбора XML-документов включает две части:ПарсериОбработчик событий。
Парсер отвечает за чтение XML-документа и отправку событий обработчику событий, таких как события начала и конца элемента.
Обработчик событий, в свою очередь, отвечает за реакцию на события и обработку переданных XML-данных.
- 1. Обработка больших файлов;
- 2. Необходимость только в части содержимого файла или только в получении конкретной информации из файла.
- 3. Когда вы хотите построить собственную объектную модель.
Чтобы обрабатывать XML с использованием подхода SAX в Python, необходимо сначала импортировать функцию parse из xml.sax, а также ContentHandler из xml.sax.handler.
Введение в методы класса ContentHandler
метод characters(content)
Когда он вызывается:
С начала строки, до встречи тега, если символы существуют, значением content являются эти строки.
От одного тега до того, как встретится следующий тег, если символы существуют, значением content являются эти строки.
От тега до момента перед встречей символа конца строки, если символы существуют, значением content являются эти строки.
Теги могут быть открывающими или закрывающими тегами.
метод startDocument()
Вызывается, когда начинается документ.
метод endDocument()
Вызывается, когда парсер достигает конца документа.
метод startElement(name, attrs)
Вызывается при обнаружении открывающего тега XML. name — имя тега, а attrs — словарь значений атрибутов тега.
метод endElement(name)
Вызывается, когда встречается закрывающий тег XML.
метод make_parser
Следующий метод создаёт новый объект парсера и возвращает его.
xml.sax.make_parser( [parser_list] )
Описание параметра:
- parser_list- Необязательный параметр, список парсеров
метод parser
Следующий метод создаёт SAX-парсер и разбирает XML-документ:
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
Описание параметра:
- xmlfile- имя XML-файла
- contenthandler- Должен быть объектом ContentHandler
- errorhandler- Если этот параметр указан, errorhandler должен быть объектом SAX ErrorHandler
Метод parseString
Метод parseString создаёт XML-парсер и разбирает XML-строку:
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
Параметры:
- xmlstring- XML-строка
- contenthandler- Должен быть объектом ContentHandler
- errorhandler- Если этот параметр указан, errorhandler должен быть объектом SAX ErrorHandler.
Примеры парсинга XML в Python
Пример
import xml.sax
class MovieHandler( xml.sax.ContentHandler ):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# Вызывается, когда начинается элемент
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print ("*****Movie*****")
title = attributes["title"]
print ("Title:", title)
# Вызывается, когда элемент заканчивается
def endElement(self, tag):
if self.CurrentData == "type":
print ("Тип:", self.type)
elif self.CurrentData == "format":
print ("Формат:", self.format)
elif self.CurrentData == "year":
print ("Год:", self.year)
elif self.CurrentData == "rating":
print ("Рейтинг:", self.rating)
elif self.CurrentData == "stars":
print ("Звёзды:", self.stars)
elif self.CurrentData == "description":
print ("Описание:", self.description)
self.CurrentData = ""
# Вызывается при чтении символов
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if ( __name__ == "__main__"):
# Создать XMLReader
parser = xml.sax.make_parser()
# Отключить пространства имён
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
# Переопределить ContextHandler
Handler = MovieHandler()
parser.setContentHandler( Handler )
parser.parse("movies.xml")
Результат выполнения приведённого выше кода следующий:
*****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Year: 2003 Rating: PG Stars: 10 Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Year: 1989 Rating: R Stars: 8 Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Stars: 10 Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Stars: 2 Description: Viewable boredom
Пожалуйста, обратитесь к полной документации SAX API.Python SAX API
Разбор XML с помощью xml.dom
Document Object Model (DOM) — это стандартный программный интерфейс, рекомендованный организацией W3C для обработки расширяемых языков разметки.
DOM-парсер при разборе XML-документа читает весь документ сразу, сохраняет все элементы документа в древовидную структуру в памяти. Затем можно использовать различные функции, предоставляемые DOM, для чтения или изменения содержимого и структуры документа, а также записывать изменённое содержимое в XML-файл.
В Python для разбора XML-файлов используется xml.dom.minidom. Пример выглядит следующим образом:
Пример
from xml.dom.minidom import parse
import xml.dom.minidom
# Открыть XML-документ с помощью парсера minidom
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print ("Корневой элемент : %s" % collection.getAttribute("shelf"))
# Получить все фильмы из коллекции
movies = collection.getElementsByTagName("movie")
# Вывести подробную информацию о каждом фильме
for movie in movies:
print ("*****Movie*****")
if movie.hasAttribute("title"):
print ("Название: %s" % movie.getAttribute("title"))
type = movie.getElementsByTagName('type')[0]
print ("Type: %s" % type.childNodes[0].data)
format = movie.getElementsByTagName('format')[0]
print ("Format: %s" % format.childNodes[0].data)
rating = movie.getElementsByTagName('rating')[0]
print ("Rating: %s" % rating.childNodes[0].data)
description = movie.getElementsByTagName('description')[0]
print ("Description: %s" % description.childNodes[0].data)
Результат выполнения вышеуказанной программы выглядит следующим образом:
Root element : New Arrivals *****Movie***** Title: Enemy Behind Type: War, Thriller Format: DVD Rating: PG Description: Talk about a US-Japan war *****Movie***** Title: Transformers Type: Anime, Science Fiction Format: DVD Rating: R Description: A schientific fiction *****Movie***** Title: Trigun Type: Anime, Action Format: DVD Rating: PG Description: Vash the Stampede! *****Movie***** Title: Ishtar Type: Comedy Format: VHS Rating: PG Description: Viewable boredom
Обратитесь к полной документации по DOM API.Python DOM APIs。
Другие расширения