Find appearance using multiple attributes in ElementTree / Python

I have the following 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> 

Q: How to find node <testcase name="VHDL_BUILD_Passthrough" status="run" time="0" classname="TestOne" /> ? I find the tree.find() function, but the name of the element seems to be the parameter of this function.

I need to find the node based on the attribute: name = "VHDL_BUILD_Passthrough" AND classname="TestOne" .

+9
python xml elementtree
source share
2 answers

It depends on which version you are using. If you have ElementTree 1.3+ (including the standard Python 2.7 library), you can use the base xpath expression as described in the documentation , for example, [@attrib='value'] :

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

Unfortunately, if you are using an earlier version of ElementTree (1.2, which is included in the standard library for python 2.5 and 2.6), you cannot use this convenience and must filter yourself.

 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'] 
+20
source share

You will have to <testcase /> over the <testcase /> elements that you have:

 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) 
0
source share

All Articles