【问题标题】:Extract items list from XML in python在python中从XML中提取项目列表
【发布时间】:2011-08-22 19:57:07
【问题描述】:

在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>

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

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

【问题讨论】:

标签: python xml lxml


【解决方案1】:

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

您可以在查询中将它们全部拼写出来,或者为自己创建一个命名空间映射,然后将其传递给 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

【讨论】:

    【解决方案2】:

    我不确定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。

    【讨论】:

    • 谢谢。 //*[local-name()="item"] 正是我所需要的。
    • 有趣,你有什么理由抱怨这个库的速度吗?
    • @MattH - 不是真的。它不是非常快,但到目前为止我还没有任何抱怨。由于易于使用,我会在返回任何其他库之前找到利用缓存的方法。
    【解决方案3】:

    我之前回答过一个类似的问题,关于如何解析和搜索 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)
    

    或者如果你使用的是字符串而不是 url:

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

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

    【讨论】:

      猜你喜欢
      • 2012-08-17
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2018-07-15
      • 1970-01-01
      • 2020-06-01
      • 2021-04-14
      • 1970-01-01
      相关资源
      最近更新 更多