Парсинг XML в Python


Что такое XML?

XML означает Extensible Markup Language (eXtensible Markup Lxtensible Markup Language).Учебник XML

XML предназначен для передачи и хранения данных.

XML — это набор правил для определения семантической разметки, который делит документ на множество частей и идентифицирует эти части.

Это также мета-язык разметки, то есть синтаксический язык, используемый для определения других семантических, структурированных языков разметки, относящихся к конкретным областям.


Парсинг XML с помощью Python

Распространённые программные интерфейсы для XML включают DOM и SAX. Эти два интерфейса по-разному обрабатывают XML-файлы и, конечно, используются в разных ситуациях.

В Python есть три способа разбора XML: SAX, DOM и ElementTree:

1.SAX (простой API для XML)

Стандартная библиотека Python включает SAX-парсер. SAX использует событийно-ориентированную модель, обрабатывая XML-файлы путём последовательного запуска событий во время разбора XML и вызова пользовательских callback-функций.

2.DOM (объектная модель документа)

Разбирает XML-данные в дерево в памяти и работает с XML, манипулируя деревом.

3. ElementTree (дерево элементов)

ElementTree похож на облегчённый DOM с удобным и дружественным API. У него хорошее удобство использования кода, высокая скорость и низкое потребление памяти.

Примечание:Поскольку DOM должен отображать XML-данные в дерево в памяти, он относительно медленный и требовательный к памяти. SAX читает XML-файлы потоковым способом, что быстрее и требует меньше памяти, но требует, чтобы пользователи реализовали callback-функции (обработчики).

Содержимое используемого в этой главе примера XML-файла movies.xml приведено ниже:

movies.xml

<collection shelf="Новые поступления"> <movie название="Враг за спиной"> <тип>Военный, триллер</тип> <формат>DVD</формат> <год>2003</год> <рейтинг>PG</рейтинг> <звёзды>10</звёзды> <описание>Разговор о войне между США и Японией</описание> </фильм> <фильм название="Трансформеры"> <тип>Аниме, научная фантастика</тип> <формат>DVD</формат> <год>1989</год> <рейтинг>R</рейтинг> <звёзды>8</звёзды> <описание>Научная фантастика</описание> </фильм> <фильм название="Триган"> <тип>Аниме, боевик</тип> <формат>DVD</формат> <эпизоды>4</эпизоды> <рейтинг>PG</рейтинг> <звёзды>10</звёзды> <описание>Вэш Ураган!</описание> </фильм> <фильм название="Иштар"> <тип>Комедия</тип> <формат>VHS</формат> <рейтинг>PG</рейтинг> <звёзды>2</звёзды> <описание>Смотрибельная скука</описание> </фильм> </коллекция>

Python использует SAX для разбора XML

SAX — это событийно-ориентированный API.

Разбор XML-документов с помощью SAX включает две части:ПарсериОбработчик событий。

Парсер отвечает за чтение 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/python # -*- coding: UTF-8 -*- 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 "*****Фильм*****" title = attributes["title"] print "Название:", 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 APIPython SAX APIs


Использование xml.dom для разбора XML

Объектная модель документа (DOM) — это стандартный программный интерфейс, рекомендованный W3C для обработки расширяемого языка разметки.

Когда DOM-парсер разбирает XML-документ, он считывает весь документ сразу и сохраняет все элементы в древовидной структуре в памяти. После этого можно использовать различные функции, предоставляемые DOM, для чтения или изменения содержимого и структуры документа, а также можно записать изменённое содержимое в XML-файл.

В Python для разбора XML-файлов используется xml.dom.minidom. Пример приведён ниже:

Пример

#!/usr/bin/python # -*- coding: UTF-8 -*- 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 "*****Фильм*****" if movie.hasAttribute("title"): print "Название: %s" % movie.getAttribute("title") type = movie.getElementsByTagName('type')[0] print "Тип: %s" % type.childNodes[0].data format = movie.getElementsByTagName('format')[0] print "Формат: %s" % format.childNodes[0].data rating = movie.getElementsByTagName('rating')[0] print "Рейтинг: %s" % rating.childNodes[0].data description = movie.getElementsByTagName('description')[0] print "Описание: %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 APIPython DOM APIs。

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