Разбор 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Содержимое следующее:

Примеры

<collection shelf="Новые поступления">
<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:

Пример

import xml.etree.ElementTree as ET

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-содержимого:

Пример

import xml.etree.ElementTree as ET

# Определите строку 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-документ с информацией о книге, а затем воспользуемся этим модулем, чтобы разобрать и обработать его:

Пример

import xml.etree.ElementTree as ET

# Создать 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

Пример

#!/usr/bin/python3

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. Пример выглядит следующим образом:

Пример

#!/usr/bin/python3

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。

Другие расширения