2012-05-31 7 views

答えて

29

AFAIK ElementTreeはXPathをサポートしていません。それは変更されましたか?

とにかく、あなたはlxmlと次のXPath式を使用することができます。

import lxml.etree 
doc = lxml.etree.parse('t.xml') 
print doc.xpath('//element[text()="A"]')[0].text 
print doc.xpath('//element[text()="A"]')[0].tag 

結果は以下のようになります。

A 
element 
9

あなたはむしろlxmlのよりも、標準ライブラリElementTreeを使用したい場合は、繰り返しを使用して、特定のテキスト値を持つすべてのサブ要素を見つけることができます。たとえば、次のように

import sys 
import xml.etree.ElementTree as etree 

s = """<root> 
    <element>A</element> 
    <element>B</element> 
</root>""" 

e = etree.fromstring(s) 

if sys.version_info < (2, 7): 
    found = [element for element in e.getiterator() if element.text == 'A'] 
else: 
    found = [element for element in e.iter() if element.text == 'A'] 

print found[0].text # This prints 'A', honestly! 

注:あなたはリスト内包であなたの要素のtext値のいくつかのストリッピングを実行することがあります。

これは、XMLツリーの任意の深さまで機能します。例えば、

s = """<root> 
    <element>A</element> 
    <element><sub>A</sub></element> 
</root>""" 

found = [element for element in e.getiterator() if element.text == 'A'] 

for f in found: 
    print f 

はあなたがXPath in ElementTreeを使用することができます

<Element element at 7f20a882e3f8> 
<Element sub at 7f20a882e4d0> 
+1

自分のタスクではメモリオーバーヘッドが非常に小さいため(CPU使用量よりもメモリが重要です)、これはlxmlから移動するために必要なコードの最後のビットであるため、lxmlよりもcElementTreeを使用しました。 – Patrick

0

を印刷します。 libをインストールする必要はありません。 @Bionicegeniusからのコメント怒鳴るが説明するように、あなたの要素は何人の兄弟を持っていない場合

config.findall('.//*[element="A"]/element') 

は、ちょうど上記の式は動作しますが、あなたは、要素ツリーでXPathを使用してのアイデアを得ます。

+0

これは問題があります所望のノードと同じレベルのすべての要素を選択する。これにより、値AとBの両方の要素が見つかります。 これを変更して検索すると、Bを検索した場合でも、値がAの要素のみが検索されます。最初の子のみが返されます。 – Bioniclegenius

関連する問題