Найти вхождение, используя несколько атрибутов в ElementTree / Python - PullRequest
9 голосов
/ 26 января 2011

У меня есть следующий XML.

<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="10" failures="0" disabled="0" errors="0" time="0.001" name="AllTests">
  <testsuite name="TestOne" tests="5" failures="0" disabled="0" errors="0" time="0.001">
    <testcase name="DefaultConstructor" status="run" time="0" classname="TestOne" />
    <testcase name="DefaultDestructor" status="run" time="0" classname="TestOne" />
    <testcase name="VHDL_EMIT_Passthrough" status="run" time="0" classname="TestOne" />
    <testcase name="VHDL_BUILD_Passthrough" status="run" time="0" classname="TestOne" />
    <testcase name="VHDL_SIMULATE_Passthrough" status="run" time="0.001" classname="TestOne" />
</testsuite>
</testsuites>

В: Как мне найти узел <testcase name="VHDL_BUILD_Passthrough" status="run" time="0" classname="TestOne" />? Я нахожу функцию tree.find(), но параметром этой функции кажется имя элемента.

Мне нужно найти узел на основе атрибута: name = "VHDL_BUILD_Passthrough" AND classname="TestOne".

Ответы [ 2 ]

20 голосов
/ 26 января 2011

Это зависит от того, какую версию вы используете.Если у вас есть ElementTree 1.3+ (включая стандартную библиотеку Python 2.7), вы можете использовать базовое выражение xpath, например, , описанное в документации , например [@attrib='value']:

x = ElmentTree(file='testdata.xml')
cases = x.findall(".//testcase[@name='VHDL_BUILD_Passthrough'][@classname='TestOne']")

К сожалению, есливы используете более раннюю версию ElementTree (1.2, включенную в стандартную библиотеку для python 2.5 и 2.6), вы не можете использовать это удобство и должны фильтровать себя.

x = ElmentTree(file='testdata.xml')
allcases = x12.findall(".//testcase")
cases = [c for c in allcases if c.get('classname') == 'TestOne' and c.get('name') == 'VHDL_BUILD_Passthrough']
0 голосов
/ 26 января 2011

Вам придется перебирать имеющиеся у вас элементы <testcase />, например:

from xml.etree import cElementTree as ET

# assume xmlstr contains the xml string as above
# (after being fixed and validated)
testsuites = ET.fromstring(xmlstr)
testsuite = testsuites.find('testsuite')
for testcase in testsuite.findall('testcase'):
    if testcase.get('name') == 'VHDL_BUILD_Passthrough':
        # do what you will with `testcase`, now it is the element
        # with the sought-after attribute
        print repr(testcase)
...