2011-01-26 6 views
8

Tengo el siguiente XML.Buscar ocurrencia utilizando múltiples atributos en ElementTree/Python

<?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: ¿Cómo puedo encontrar el nodo <testcase name="VHDL_BUILD_Passthrough" status="run" time="0" classname="TestOne" />? Encuentro la función tree.find(), pero el parámetro de esta función parece ser el nombre del elemento.

Necesito encontrar el nodo basado en el atributo: name = "VHDL_BUILD_Passthrough" AND classname="TestOne".

+0

¿Su etiqueta 'testsuite' no está cerrada? – eumiro

+0

@eumiro: fue un error tipográfico, gracias por señalarlo. – prosseek

Respuesta

17

Esto depende de la versión que está utilizando. Si tiene elementtree 1.3+ (incluido en Python 2.7 biblioteca estándar) se puede utilizar una expresión básica de XPath, como described in the docs, como [@attrib=’value’]:

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

Desafortunadamente, si usted está utilizando una versión anterior de elementtree (1.2, incluida en la biblioteca estándar para python 2.5 y 2.6) no puede usar esa conveniencia y necesita filtrarse usted mismo.

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

+1 Has guardado el día ... gracias :) – ATOzTOA

0

Vas a tener que repetir por los <testcase /> elementos que usted tiene, de este modo:

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) 
Cuestiones relacionadas