В python лучший способ извлечь список элементов из следующего xml?
<iq xmlns="jabber:client" to="__anonymous__admin@localhost/8978528613056092673206"
from="conference.localhost" id="disco" type="result">
<query xmlns="http://jabber.org/protocol/disco#items">
<item jid="[email protected]" name="pgatt (1)"/>
<item jid="[email protected]" name="pgatt (1)"/>
</query>
</iq>
Обычно я использую lxml с xpath, но в этом случае он не работает. Я думаю, что мои проблемы связаны с пространствами имен. Я не установлен в lxml и открыт для использования любой библиотеки.
Я бы хотел, чтобы решение было достаточно устойчивым, чтобы сбой, если общая структура xml изменилась.
Я не уверен в lxml
, но вы можете использовать выражение типа //*[local-name()="item"]
, чтобы вытащить элементы item
, независимо от их пространства имен.
Вы также можете посмотреть Amara для обработки XML.
>>> import amara.bindery
>>> doc = amara.bindery.parse(
... '''<iq xmlns="jabber:client"
... to="__anonymous__admin@localhost/8978528613056092673206"
... from="conference.localhost" id="disco" type="result">
... <query xmlns="http://jabber.org/protocol/disco#items">
... <item jid="[email protected]" name="pgatt (1)"/>
... <item jid="[email protected]" name="pgatt (1)"/>
... </query>
... </iq>''')
>>> for item in doc.iq.query.item:
... print item.jid, item.name
...
[email protected] pgatt (1)
[email protected] pgatt (1)
>>>
Как только я обнаружил Amara, я бы никогда не рассматривал обработку XML каким-либо другим способом.
//*[local-name()="item"]
было именно то, что мне нужно.
Я ответил на аналогичный вопрос ранее о том, как анализировать и искать через XML-данные.
Полнотекстовый поиск XML-данных с помощью Python: лучшие практики, плюсы и минусы
Вам нужно посмотреть на функцию xml2json. Функция ожидает объект мини-объекта. Вот как я получил свой xml, не уверен, как вы это делаете.
from xml.dom import minidom
x = minidom.parse(urllib.urlopen(url))
json = xml2json(x)
Или, если вы используете строку, а не URL-адрес:
x = minidom.parseString(xml_string)
json = xml2json(x)
Затем функция xml2json вернет словарь со всеми значениями, найденными в xml. Возможно, вам придется попробовать его и распечатать вывод, чтобы увидеть, как выглядит макет.
Я пропустил лодку, но здесь, как вы это делаете, заботясь о пространствах имен.
Вы можете либо записать их в запросе, либо сделать себе карту пространства имен, которую вы передаете в запрос xpath.
from lxml import etree
data = """<iq xmlns="jabber:client" to="__anonymous__admin@localhost/8978528613056092673206"
from="conference.localhost" id="disco" type="result">
<query xmlns="http://jabber.org/protocol/disco#items">
<item jid="[email protected]" name="pgatt (1)"/>
<item jid="[email protected]" name="pgatt (1)"/>
</query>
</iq>"""
nsmap = {
'jc': "jabber:client",
'di':"http://jabber.org/protocol/disco#items"
}
doc = etree.XML(data)
for item in doc.xpath('//jc:iq/di:query/di:item',namespaces=nsmap):
print etree.tostring(item).strip()
print "Name: %s\nJabberID: %s\n" % (item.attrib.get('name'),item.attrib.get('jid'))
Выдает:
<item xmlns="http://jabber.org/protocol/disco#items" jid="[email protected]" name="pgatt (1)"/>
Name: pgatt (1)
JabberID: [email protected]
<item xmlns="http://jabber.org/protocol/disco#items" jid="[email protected]" name="pgatt (1)"/>
Name: pgatt (1)
JabberID: [email protected]