XML-сервисы на Python. Часть первая. Создание и парсинг XML.

02 May 2007


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

Говоря в общем, встроенная в последний Python (2.5) ElementTree не совсем хороший выбор, как по мне, для полноценной работы с XML. С помощью ElementTree удобно создавать XML-документы, но никак не парсить. Я был удивлен, что такая простая задача как принять XML-документ из переменной — окажется такой замороченной… ElementTree заточен для парсинга файлов (т.е. ему нужно передавать при открытии или путь или уже открытый файл). В моем случае я уже имел переменную из HTTP-запроса, обработанного Django. Несколько часов я плясал с бубном, сначала чтобы заставить принять XML-документ из переменной, потом уже с самим парсингом и получением аттрибутов тегов. В общем убил много времени впустую, что очень неприятно.
В довесок ко всему общеизвестный факт что ElementTree имеет очень ограниченную документацию, поэтому время было потрачено дополнительно на гугление и ковыряние в его сырцах.

Хочу отметить что создание XML-документа с помощью ElementTree оказалось достаточно простым и удобным. А начинали мы именно с создания, поэтому и парсинг позже пытались делать тем же ElementTree.

В итоге, после всей возни, я решил для парсинга использовать отдельную библиотеку — Beautilful Soup.
И работа сразу пошла очень быстро. Главное достоинство Beautilful Soup — это практически полная сериализация XML-документа в объекты Python. Что очень хорошо отражается на читаемости кода и очень удобно при отладке. Насчет создания документов с помощью Beautilful Soup, ничего сказать не могу, т.к. небыло времени для себя потестировать.

Из прошлого своего опыта также добавлю, что есть еще одна библиотека для работы с XML на Python — lxml.
Она базируется на Cи библиотеках libxml и libxslt. Которые в свою очередь используются в большом количестве unix-приложений и других скриптовых языках.
Прошлая моя задача была свзязана с выборкой данных из XML-документов с помощью Xpath. Так вот lxml и в частности libxml имеет хорошую и удобную реализацию Xpath. Так что рекомендую.

PS: Все написанное выше — сугубо личное мнение, на которое в принципе имею право :)

Ниже примеры кода.

  1. пример парсинга XML через Soup
    from BeautifulSoup import BeautifulStoneSoup as Soup

def some_view(request):
message = Soup(request.raw_post_data)
some_obj = Obj(content = message.body.string, phone = message.sin.string)

  1. message.body – body это xml тег

  1. пример создания XML-документа
    import elementtree.ElementTree as ET
  1. создаем документ
    root = ET.Element(“message”) # рутовый элемент
    root.set(“rid”, “7idfndsi9s”) # устанавливаем ему аттрибут
    sn = ET.SubElement(root, “sn”)
    sn.text = “1039303”
    body = ET.SubElement(root, “body”)
    body.set(“content-type”,“text/plain”)
    body.text = “somte text content”
    message = ET.tostring(root)

Вот такой код генериться (из предыдущего примера)
<message rid="7idfndsi9s"> <sn>1039303</sn> <body content-type="text/plain">somte text content</body>