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

Если вы хотите использовать стандартную библиотеку ElementTree, а не LXML, вы может использовать итерацию для поиска всех подэлементов с определенным текстовым значением. Например:

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> 
+1

Я выбрал использовать cElementTree над lxml, так как для моей задачи он имеет намного меньшие накладные расходы памяти (память более критична, чем использование ЦП), это был последний бит кода, который мне нужно переместить из lxml – Patrick

0

Вы можете использовать XPath in ElementTree. Нет необходимости устанавливать lib.

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

Как комментарий ниже от @Bionicegenius объясняет, приведенное выше выражение просто работает, если ваш элемент не имеет братьев, но вы получите идею использования XPath в дереве элементов.

+0

У этой проблемы выбора всех элементов на том же уровне, что и нужный узел. Это найдет оба элемента со значениями A и B. Если вы измените его, чтобы найти, тогда он будет только когда-либо найти элемент со значением A, даже если вы ищите B - он вернет только первый ребенок. – Bioniclegenius

Смежные вопросы