2011-05-10 8 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についてはわかりませんが、item要素をネームスペースに関係なく引き出すには、//*[local-name()="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 - 実際はありません。それは驚くほど高速ではありませんが、私はこれまでのところ苦情は​​ありませんでした。使いやすさで、私は他のlibのいずれかに戻る前にキャッシュを利用する方法を見つけるでしょう。 –

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) 

それとも、文字列ではなく、URLを使用する場合:

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] 
関連する問題