Skip to content

ElementTree

Если текст, который необходимо проанализировать, имеет формат XML, скорее всего вам придется подходить к решению этой проблемы с несколько иной стороны, чем, например, к анализу обычных текстовых файлов журналов. Едва ли вы захотите читать такие файлы строку за строкой и выполнять поиск по шаблону, и едва ли получится широко использовать регулярные выражения. В формате XML используется древовидная структура организации данных, поэтому подход, основанный на построчном чтении, здесь не годится. И использование регулярных выражений для построения древовидной структуры данных легко может превратиться в кошмар.

Что же тогда делать? Для работы с форматом XML обычно используется один из двух подходов. Существует такая вещь, как «simple API for XML» (простой прикладной интерфейс для работы с форматом XML), или SAX. Стандартная библиотека языка Python имеет в своем составе анализатор SAX. Он обладает высокой скоростью работы и потребляет совсем немного памяти при анализе XML. Но он основан на применении функций обратного вызова, поэтому для определенных частей данных, когда встречаются такие разделы документа XML, как открывающий и закрывающий теги, он просто вызывает определенные методы. Это означает, что вам придется задать обработчики для данных и самостоятельно отслеживать информацию о состоянии, что может оказаться далеко не простым делом. Это делает утверждение «simple» (простой) в названии «simple API for XML» не совсем соответствующим истине. Другой подход к обработке XML заключается

в использовании объектной модели документа (Document Object Model, DOM). В состав стандартной библиотеки языка Python входит и библиотека DOM XML. Как правило, анализатор DOM не отличается высокой скоростью работы и потребляет больше памяти, чем SAX, потому что он считывает дерево XML в память целиком и создает отдельные объекты для каждого узла дерева. Преимущество использования DOM заключается в том, что вам не придется отслеживать информацию о состоянии, так как каждый узел хранит информацию о родительских и дочерних узлах. Однако прикладной интерфейс DOM в лучшем случае приходится признать достаточно громоздким.

Имеется и третья возможность - ElementTree. ElementTree - это библиотека синтаксического анализа XML, которая входит в состав стандартной библиотеки языка Python, начиная с версии Python 2.5. Библиотеку ElementTree можно представить себе, как легковесный анализатор DOM, с простым и удобным прикладным интерфейсом. В дополнение к простоте и удобству в использовании этот анализатор потребляет незначительный объем памяти. Мы настоятельно рекомендуем использовать ElementTree. Если у вас возникнет потребность выполнять синтаксический анализ документов XML, попробуйте сначала воспользоваться библиотекой ElementTree.

Чтобы с помощью ElementTree приступить к анализу файла в формате XML, достаточно просто импортировать библиотеку и передать требуемый файл функции parse():

Здесь, чтобы сократить объем ввода с клавиатуры при работе с библиотекой, мы импортировали модуль ElementTree под именем ЕТ. Далее, мы предложили библиотеке выполнить разбор XML-файла со списком пользователей, полученного от механизма сервлетов Tomcat. Объект, созданный библиотекой ElementTree, мы назвали tcusers. Объект tcus-ers имеет тип xml.etree.ElementTree.ElementTree.

Мы удалили из файла пользователей сервера Tomcat примечания о порядке использования и текст лицензионного соглашения, в результате он принял следующий вид:

Во время разбора XML-файла метод parse() из библиотеки ElementTree создает и возвращает объект дерева, ссылка на который записывается в переменную tcusers. После этого данная переменная может использоваться для организации доступа к различным узлам дерева в файле XML. Наибольший интерес для нас представляют два метода этого объекта: find() и findall(). Метод find() отыскивает первый узел, соответствующий запросу, который ему передается, и возвращает объект Element, представляющий этот узел. Метод findall() отыскивает все узлы, соответствующие запросу, и возвращает список объектов Element, которые представляют эти узлы.

Перечень шаблонов, которые можно передавать методам find() и find-all(), ограничен подмножеством выражений на языке XPath. В качестве критериев поиска можно указывать имя тега, символ «*», соответствующий всем дочерним элементам; символ «.», соответствующий текущему узлу; и комбинацию «//», соответствующую всем подчиненным узлам, начиная от точки поиска. Символ слеша (/) может использоваться в качестве разделителя критериев поиска. С помощью метода find() и имени тега мы попробовали отыскать первый узел user в файле пользователей Tomcat:

Мы передали методу find() критерий "/user". Начальный символ слеша указывает на абсолютный путь с началом в корневом узле. Текст 'user' определяет имя тега, который требуется отыскать. Отсюда следует, что метод find() вернет первый узел с тегом user. Здесь видно, что объект с именем first_user принадлежит к типу Element.

В число наиболее интересных для нас методов и атрибутов объекта Element входят attrib, find(), findall(), get(), tag и text. Атрибут attrib-это словарь атрибутов, принадлежащих данному объекту Element. Методы find() и findall() этого объекта работают точно так же, как одноименные методы объекта ElementTree. Метод get() используется для извлечения указанного атрибута из словаря атрибутов текущего тега XML. Атрибут tag содержит имя тега текущего объекта Element. Атрибут text содержит текст, расположенный в текстовом узле текущего объекта Element.

Теперь попробуем обратиться к методам и атрибутам объекта tcusers:

Ниже приводится элемент документа XML, соответствующий объекту

Теперь, когда вы получили некоторое представление о возможностях библиотеки ElementTree, рассмотрим более сложный пример. Мы выполним разбор файла пользователей Tomcat и отыщем все узлы user, где значение атрибута name соответствует значению, заданному нами (в данном случае 'tomcat'), как показано в примере 3.27.

Пример 3.27. Разбор файла пользователей Tomcat с помощью библиотеки ElementTree

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

В заключение ниже приводится пример использования библиотеки ElementTree для извлечения некоторой информации из неудачно сформированного фрагмента XML. В операционной системе Mac OS X имеется утилита с именем system_profiler, которая отображает информацию о системе. Формат XML является одним из выходных форматов, которые поддерживает утилита system_profiler, но похоже, что поддержка формата XML была добавлена в самый последний момент. Мы предполагаем извлечь информацию о версии операционной системы, которая содержится в следующем фрагменте файла XML:

Вы спросите, почему на наш взгляд этот фрагмент XML оформлен неудачно? Дело в том, что ни в одном из тегов XML нет ни одного атрибута. В основной своей массе теги представляют типы данных. И такие теги с переменными значениями, как key и string, заключены в один и тот же родительский тег. Взгляните на пример 3.28.

Пример 3.28. Разбор файла, полученного в результате вызова утилиты system orofiler в Mac OS X

Сценарий отыскивает все теги diet, в которых имеется дочерний элемент string с текстом 'SPSoftwareataType'. Информация, которую требуется извлечь, находится в этом узле. В этом примере используется единственный метод, который не обсуждался ранее, - это метод get-children(). Он просто возвращает список дочерних узлов указанного элемента. Кроме того, этот пример достаточно ясен, хотя сам файл XML можно было бы оформить лучше. Ниже приводится результат, полученный от сценария, когда он был запущен на ноутбуке, работающем под управлением операционной системы Mac OS X Tiger:

Библиотека стала прекрасным дополнением к стандартной библиотеке языка Python. Мы долгое время пользуемся ею и рады, что у нас есть такая возможность. Вы можете попробовать пользоваться библиотеками SAX и DOM, имеющимися в стандартной библиотеке языка Python, но мы думаем, что рано или поздно вы вернетесь к библиотеке ElementTree.

Комментарии (0)

RSS feed Comments

Написать комментарий

smaller | bigger

busy
 

Регистрация




Top