XML-сервисы на Python. Часть первая. Создание и парсинг XML. 2
Недавно второй раз на практике столкнулся с серьезной задачей по работе с 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: Все написанное выше—сугубо личное мнение, на которое в принципе имею право :)
Ниже примеры кода.
# пример парсинга 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)
# message.body - body это xml тег# пример создания XML-документа
import elementtree.ElementTree as ET
# создаем документ
root = ET.Element("message") # рутовый элемент <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>
</message>Trackbacks
Use the following link to trackback from your own site:
http://livedev.org/trackbacks?article_id=xml-services-with-python-p1&day=02&month=05&year=2007







На деле, не так уж и плохо все с парсингом у ET:
s = '...' # some XML import xml.etree.ElementTree as ET from StringIO import StringIO sio = StringIO(s) xml = ET.parse(sio)
А можно вообще прямо из коннекта читать:
data = urlopen('http://...') xml = ET.parse(data)
С Django'вским request'ом это, правда, действительно не очень удобно, было бы неплохо ему файловый интерфейс прикрутить, чтобы делать ET.parse(request)...
То что читать из файла действительно не сильно страшно. Вот сам интерфейс работы с отпарсенным XML-документом не такой прозрачный как хотелось бы. Тот же суп (Soup) делает все на порядок красивее все-таки.