Разбираем XML стандартными средствами Python

Стандартная библиотека языка Python уже содержит готовый XML анализатор (парсер). Доступ к нему осуществляется через пакет xml.

 Или другой вариант:

 Парсер поддерживает загрузку XML документов как непосредственно из файла, так и обычной строки. Объект парсера создаётся в зависимости от источника XML данных (файл или строка) одним из следующих методов.


Загрузка из файла:

 Загрузка из строки:

 По завершению инициализации настоятельно рекомендуется вызвать метод normalize для слияния разрозненных фрагментов текста воедино. В противном случае при разборе XML могут возникнуть ошибки.

 Рассмотрим разбор XML на примере следующего XML документа.

 В документе имеется корневой элемент test, два обычных узла node1 (имеет атрибут attr) и node2, а также узел array, представляющий собой, по сути, массив некоторых данных.

Данный пример уже использовался для разбора XML в Delphi. Сегодня же мы будем выполнять его анализ средствами Python.

Загрузим XML документ.

Разбор простого узла

Для поиска узлов по названию тега служит метод getElementsByTagName(tagName). Этот метод возвращает список тегов с именем указанным в качестве параметра. Если тег с таким именем только один, можно сразу обратиться к нему по индексу 0.

 Название тега можно получить с помощью свойства nodeName

 Значение атрибута по его имени можно получить с помощью метода getAttribute(attributeName).

 Также значение атрибута тега можно получить с помощью коллекции attributes, обратившись к нему по его индексу. Однако такой подход оправдан скорее при обходе атрибутов тега в цикле, чем при работе с отдельно взятым атрибутом.

 Получить значение тега несколько сложнее. Для этого необходимо вначале обратиться к первому дочернему узлу через коллекцию childNodes (с точки зрения стандартного парсера Python значение тега это почему-то дочерний узел) и только после этого получить само значение через свойство nodeValue.

Разбор сложного узла на примере массива

Узел, обозначенный тегом array, содержит настоящий массив элементов. Однако его разбор не представляет особой сложности. Сначала получаем нужный дочерний узел через коллекцию childNodes или метод getElementsByTagName и работаем с ним как с простым узлом.

В качестве примера рассмотрим обход дочерних узлов в цикле.

 Данная запись цикла for в Python по смыслу соответствует циклу foreach в C# или PHP.

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

Например.

 Однотипная обработка содержимого такого узла невозможна. Необходимо распознавать тип узла и в соответствии с ним уже выполнять соответствующие действия.

Распознаются несколько типов узлов, но основных из них три.

  • DOCUMENT_NODE – документ;
  • ELEMENT_NODE – элемент. Обычный узел;
  • TEXT_NODE – текст. Этот тип узла соответствует значению тега.

Выполним разбор приведённого выше сложного узла с учётом данных замечаний.

 Сравнение со стандартными парсерами некоторых других языков

Стандартный XML парсер Python не отличается удобством и значительно уступает по своим возможностям другим парсерам даже для самого Python (тому же lxml). При этом, главным недостатком как в отношении удобства так и функционала является, конечно, отсутствие возможности работать с XML иначе как средствами DOM в сочетании с явно недостаточно продуманной объектной моделью и, как следствие, неоправданно громоздким инструментарием.

Для сравнения. TXMLDocument в Delphi также работает только с DOM, но разбор структуры документа с его помощью гораздо проще и удобнее во многом благодаря отсутствию необходимости создавать в коде сложные конструкции наподобие тех, что разработчик вынужден использовать в Python.

Что касается работы с XML в .NET Framework, то здесь нет смысла даже сравнивать. LINQ to XML, поддержка XPath «из коробки» … К счастью, в Iron Python всё это доступно.

Конечно, возможностей стандартного парсера вполне достаточно для решения задач практически любой степени сложности. Только каковы издержки реализации на его основе?..

Один комментарий

  1. Большое спасибо! Долго думал как начать работать с XML потоками Сейчас вроде бы разобрался

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *