web-dev-qa-db-ja.com

ElementTreeでXPathを使用してテキストで要素を検索する

次のようなXMLが与えられます。

<root>
    <element>A</element>
    <element>B</element>
</root>

ElementTreeとXPathのサポートを使用して、要素をコンテンツAと一致させるにはどうすればよいですか?ありがとう

13
pistacchio

AFAIKElementTreeは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
32
brandizzi

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

印刷します

<Element element at 7f20a882e3f8>
<Element sub at 7f20a882e4d0>
10
Chris

ElementTreeのXPath を使用できます。 libをインストールする必要はありません。

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

@Bionicegeniusからの以下のコメントで説明されているように、上記の式は、要素にシビリングがない場合にのみ機能しますが、アイデアは得られます。 ElementTreeでXPathを使用することは可能であり、これが最も簡単なソリューションです。

4
neves