2011-05-10 58 views
1

在python中,從以下xml中提取項目列表的最佳方式是什麼?在Python中從XML中提取項目列表

<iq xmlns="jabber:client" to="[email protected]/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> 

我通常在xpath中使用lxml,但在這種情況下它不起作用。我認爲我的問題是由於命名空間。我沒有設置lxml,並且可以使用任何庫。

我想要一個足夠強大的解決方案,如果xml的一般結構發生變化,就會失敗。

+0

也許你應該看看http://stackoverflow.com/questions/1953761/accessing-xmlns-attribute-with-python-elementree – Donovan

+0

你想要什麼樣的信息提取? – MattH

回答

1

我不確定lxml,但您可以使用類似//*[local-name()="item"]的表達式來提取item元素,而不考慮其名稱空間。

您可能還想看看Amara的XML處理。

>>> import amara.bindery 
>>> doc = amara.bindery.parse(
...  '''<iq xmlns="jabber:client" 
...   to="[email protected]/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。

+0

謝謝。 '// * [local-name()=「item」]'正是我所需要的。 – Gattster

+0

有趣的是,你有什麼理由抱怨這個圖書館的速度? – MattH

+0

@MattH - 不是。雖然速度並不快,但迄今爲止我還沒有任何抱怨。隨着易於使用,我會找到方法來利用緩存之前,我可以回到任何其他庫。 –

1

我以前回答過類似的問題,關於如何解析和搜索XML數據。

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

你會想看看xml2json功能。 該函數需要一個小型對象。這是我得到我的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中找到的所有值的字典。您可能需要嘗試一下並打印輸出以查看佈局的樣子。

0

我錯過了這條船,但這裏是關於命名空間的過程。

您可以在查詢中將它們全部拼出,或者讓自己成爲傳遞給xpath查詢的名稱空間映射。

from lxml import etree 

data = """<iq xmlns="jabber:client" to="[email protected]/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]