在python中从XML中提取项目列表

时间:2011-05-10 21:18:49

标签: python xml lxml

在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="pgatt@conference.localhost" name="pgatt (1)"/>
        <item jid="pgatt@conference.localhost" name="pgatt (1)"/>
    </query>
</iq>

我通常在xpath中使用lxml,但在这种情况下它不起作用。我认为我的问题是由命名空间引起的。我没有设置lxml并且可以使用任何库。

如果xml的一般结构发生变化,我想要一个足够强大的解决方案。

3 个答案:

答案 0 :(得分:1)

我不确定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="pgatt@conference.localhost" name="pgatt (1)"/>
...            <item jid="pgatt@conference.localhost" name="pgatt (1)"/>
...          </query>
...        </iq>''')
>>> for item in doc.iq.query.item:
...   print item.jid, item.name
...
pgatt@conference.localhost pgatt (1)
pgatt@conference.localhost pgatt (1)
>>>

一旦我发现了Amara,我绝不会考虑以其他方式处理XML。

答案 1 :(得分:1)

之前我回答了类似的问题,关于如何解析和搜索xml数据。

Full text searching XML data with Python: best practices, pros & cons

您需要查看xml2json函数。 该函数需要一个minidom对象。这就是我获取xml的方式,不知道你是怎么做的。

from xml.dom import minidom
x = minidom.parse(urllib.urlopen(url))
json = xml2json(x)

或者如果您使用字符串而不是网址:

x = minidom.parseString(xml_string)
json = xml2json(x)

然后xml2json函数将返回一个字典,其中包含在xml中找到的所有值。您可能必须尝试并打印输出以查看布局的样子。

答案 2 :(得分:0)

我错过了这条船,但是这里是你在关心命名空间时如何做到的。

您可以在查询中拼写它们,也可以自己创建一个命名空间映射,然后传递给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="pgatt@conference.localhost" name="pgatt (1)"/>
        <item jid="pgatt@conference.localhost" 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="pgatt@conference.localhost" name="pgatt (1)"/>
Name: pgatt (1)
JabberID: pgatt@conference.localhost

<item xmlns="http://jabber.org/protocol/disco#items" jid="pgatt@conference.localhost" name="pgatt (1)"/>
Name: pgatt (1)
JabberID: pgatt@conference.localhost