Обработка XML в Python

Я собираюсь создать часть проекта, которая должна будет создать и опубликовать XML-документ в веб-сервисе, и я хотел бы сделать это на Python, как средство для расширения моих навыков в нем.

К сожалению, хотя я достаточно хорошо знаю модель XML в .NET, я не уверен, каковы плюсы и минусы моделей XML в Python.

У кого-нибудь есть опыт обработки XML в Python? С чего бы вы посоветовали мне начать? Файлы XML, которые я буду создавать, будут довольно простыми.

Ответов (12)

Решение

Лично я поиграл с несколькими встроенными опциями в проекте, насыщенном XML, и остановился на Pulldom как на лучшем выборе для менее сложных документов.

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

Что мне нравится: вы можете обрабатывать синтаксический анализ в for цикле, а не использовать обратные вызовы. Вы также откладываете полный синтаксический анализ (часть "извлечения") и получаете дополнительную информацию только при звонке expandNode() . Это удовлетворяет мои общие требования к "ответственной" эффективности без ущерба для простоты использования и простоты.

Вы также можете попробовать untangle для анализа простых XML-документов.

Если вы собираетесь создавать сообщения SOAP, ознакомьтесь с soaplib . Он использует ElementTree под капотом, но предоставляет гораздо более чистый интерфейс для сериализации и десериализации сообщений.

Настоятельно рекомендую SAX - Simple API for XML - реализация в библиотеках Python. Их довольно легко настроить и обработать XML даже за счет управления API, как обсуждалось в предыдущих плакатах, и они имеют небольшой объем памяти, в отличие от парсеров DOM стилей проверки XML .

Для серьезной работы с XML в Python используйте lxml

Python поставляется со встроенной библиотекой ElementTree, но lxml расширяет ее с точки зрения скорости и функциональности (проверка схемы, синтаксический анализ sax, XPath, различные виды итераторов и многие другие функции).

Вам необходимо установить его, но во многих местах он уже считается частью стандартного оборудования (например, Google AppEngine не разрешает использование пакетов Python на основе C, но делает исключение для lxml, pyyaml ​​и некоторых других).

Создание XML-документов с помощью E-factory (из lxml)

Ваш вопрос касается создания XML-документа.

В lxml есть много методов, и мне потребовалось время, чтобы найти тот, который кажется простым в использовании и легким для чтения.

Пример кода из lxml-документа по использованию E-factory (немного упрощен):


E-factory предоставляет простой и компактный синтаксис для генерации XML и HTML:

>>> from lxml.builder import E

>>> html = page = (
...   E.html(       # create an Element called "html"
...     E.head(
...       E.title("This is a sample document")
...     ),
...     E.body(
...       E.h1("Hello!"),
...       E.p("This is a paragraph with ", E.b("bold"), " text in it!"),
...       E.p("This is another paragraph, with a", "\n      ",
...         E.a("link", href="http://www.python.org"), "."),
...       E.p("Here are some reserved characters: <spam&egg>."),
...     )
...   )
... )

>>> print(etree.tostring(page, pretty_print=True))
<html>
  <head>
    <title>This is a sample document</title>
  </head>
  <body>
    <h1>Hello!</h1>
    <p>This is a paragraph with <b>bold</b> text in it!</p>
    <p>This is another paragraph, with a
      <a href="http://www.python.org">link</a>.</p>
    <p>Here are some reserved characters: &lt;spam&amp;egg&gt;.</p>
  </body>
</html>

Я ценю на E-factory следующие вещи

Код читается почти как получившийся XML-документ

Читаемость имеет значение.

Позволяет создавать любой XML-контент

Поддерживает такие вещи, как:

  • использование пространств имен
  • начальный и конечный текстовые узлы в одном элементе
  • функции форматирования содержимого атрибута (см. func CLASS в полном примере lxml )

Позволяет создавать очень удобочитаемые конструкции со списками

например:

from lxml import etree
from lxml.builder import E
lst = ["alfa", "beta", "gama"]
xml = E.root(*[E.record(itm) for itm in lst])
etree.tostring(xml, pretty_print=True)

в результате чего:

<root>
  <record>alfa</record>
  <record>beta</record>
  <record>gama</record>
</root>

Выводы

Я настоятельно рекомендую прочитать руководство по lxml - оно очень хорошо написано и даст вам еще много причин использовать эту мощную библиотеку.

Единственный недостаток lxml в том, что его нужно компилировать. См. Ответ SO для получения дополнительных советов, как установить lxml из пакета формата wheel за доли секунды.

Поскольку вы упомянули, что будете создавать «довольно простой» XML, модуль minidom (часть стандартной библиотеки Python), скорее всего, удовлетворит ваши потребности. Если у вас есть опыт работы с DOM-представлением XML, вы должны найти API довольно простым.

ElementTree имеет приятный API Python. Я думаю, что он даже поставляется как часть python 2.5.

Он написан на чистом питоне и, как я уже сказал, довольно хорош, но если вам понадобится больше производительности, то lxml предоставляет тот же API и использует libxml2 под капотом. Теоретически вы можете просто заменить его, когда обнаружите, что он вам нужен.

Я пишу сервер SOAP, который принимает запросы XML и создает ответы XML. (К сожалению, это не мой проект, поэтому он закрытый, но это еще одна проблема).

Для меня оказалось, что создание (SOAP) XML-документов довольно просто, если у вас есть структура данных, которая "соответствует" схеме.

Я сохраняю конверт, так как конверт ответа (почти) такой же, как конверт запроса. Затем, поскольку моя структура данных является (возможно, вложенным) словарем, я создаю строку, которая превращает этот словарь в элементы <key> value </key>.

Это задача, которую упрощает рекурсия, и я получаю правильную структуру. Все это делается в коде Python и в настоящее время достаточно быстро для промышленного использования.

Вы также можете (относительно) легко создавать списки, хотя в зависимости от вашего клиента вы можете столкнуться с проблемами, если не укажете длину.

Для меня это было намного проще, так как словарь - это гораздо более простой способ работы, чем какой-либо настраиваемый класс. Для книг генерировать XML намного проще, чем разбирать!

В общем, существует 3 основных способа работы с XML: dom, sax и xpath. Модель dom хороша, если вы можете позволить себе загрузить весь XML-файл в память сразу, и вы не против иметь дело со структурами данных, и вы просматриваете большую / большую часть модели. Модель sax хороша, если вас интересуют только несколько тегов и / или вы имеете дело с большими файлами и можете обрабатывать их последовательно. В модели xpath есть немного каждой из них - вы можете выбирать пути к нужным вам элементам данных, но для этого требуется больше библиотек.

Если вам нужен простой и упакованный с Python, minidom - ваш ответ, но он довольно неубедительный, а документация гласит: «Вот документы по dom, пойди, разберись». Это действительно раздражает.

Лично мне нравится cElementTree, которая является более быстрой (на основе c) реализацией ElementTree, которая представляет собой модель, похожую на dom.

Я использовал системы саксофона, и во многих отношениях они более «питонические» по своему ощущению, но я обычно заканчиваю тем, что создаю системы на основе состояний для их обработки, и в этом заключается безумие (и ошибки).

Я советую использовать minidom, если вам нравится исследование, или ElementTree, если вам нужен хороший код, который хорошо работает.

Я предполагаю, что способ обработки XML в .NET основан на некоторой версии MSXML, и в этом случае я предполагаю, что использование, например, minidom позволит вам почувствовать себя как дома. Однако, если вы выполняете простую обработку, то, вероятно, подойдет любая библиотека.

Я также предпочитаю работать с ElementTree при работе с XML в Python, потому что это очень удобная библиотека.

Я использовал ElementTree для нескольких проектов и рекомендую его.

Он питонический, поставляется «в коробке» с Python 2.5, включая cElementTree c-версии (xml.etree.cElementTree), которая в 20 раз быстрее, чем чистая версия Python, и очень проста в использовании.

lxml имеет некоторые преимущества в производительности, но они неравномерны, и вам следует сначала проверить тесты производительности для вашего варианта использования.

Насколько я понимаю, код ElementTree легко портируется в lxml.

Это немного зависит от того, насколько сложным должен быть документ.

Я много использовал minidom для написания XML, но обычно это просто чтение документов, выполнение некоторых простых преобразований и их обратная запись. Это работало достаточно хорошо, пока мне не понадобилась возможность упорядочивать атрибуты элементов (чтобы удовлетворить древнее приложение, которое не анализирует XML должным образом). В этот момент я сдался и сам написал XML.

Если вы работаете только с простыми документами, то сделать это самому может быть быстрее и проще, чем изучать фреймворк. Если вы, возможно, можете написать XML вручную, то вы, вероятно, также можете закодировать его вручную (просто не забудьте правильно экранировать специальные символы и использовать str.encode(codec, errors="xmlcharrefreplace") ). Помимо этих сбоев, XML достаточно регулярен, и для его написания не требуется специальная библиотека. Если документ слишком сложен для написания вручную, вам, вероятно, следует изучить один из уже упомянутых фреймворков. Ни в коем случае вам не нужно писать общий модуль записи XML.