accessing children by key attribute

59 views Asked by At

Using xml.etree I need to access an element by a key identifier.

Having as an example

<?xml version="1.0" encoding="utf-8" ?>
<Models>
    <Model Id="1" Name="booname" Description="boo" Filter="b">
        <ModelVariables>
            <Variable Id="1" Token="tothh"  />
            <Variable Id="2" Token="avgtt"  />
        </ModelVariables>
        <Terms>
            <Term Id="1" Description="ln1"  Coefficient="0.24160834" />
            <Term Id="2" Description="ln2"  Coefficient="-0.09360441" />
        </Terms>
    </Model>
    <Model Id="2" Name="fooname" Description="foo" Filter="f">
        <Terms>
            <Term Id="1" Description="e1"  Coefficient="0.36310718" />
            <Term Id="2" Description="e2"  Coefficient="-0.24160834" />
        </Terms>
    </Model>
</Models>

How can i access the elements according to the id value? If the argument 2 is passed, whats the most direct way to access all the attributes for model fooname?

I've tried to use findtext, find, and get methods with a variation of arguments but i cant access the desired element.

1

There are 1 answers

0
alecxe On BEST ANSWER

xml.etree.ElementTree supports a limited XPath language functionality, but this is enough to get an element by a specific value of an attribute:

import xml.etree.ElementTree as ET

data = """<?xml version="1.0" encoding="utf-8" ?>
<Models>
    <Model Id="1" Name="booname" Description="boo" Filter="b">
        <ModelVariables>
            <Variable Id="1" Token="tothh"  />
            <Variable Id="2" Token="avgtt"  />
        </ModelVariables>
        <Terms>
            <Term Id="1" Description="ln1"  Coefficient="0.24160834" />
            <Term Id="2" Description="ln2"  Coefficient="-0.09360441" />
        </Terms>
    </Model>
    <Model Id="2" Name="fooname" Description="foo" Filter="f">
        <Terms>
            <Term Id="1" Description="e1"  Coefficient="0.36310718" />
            <Term Id="2" Description="e2"  Coefficient="-0.24160834" />
        </Terms>
    </Model>
</Models>"""

root = ET.fromstring(data)

id_value = "2"
model = root.findall(".//Model[@Id='%s']" % id_value)[0]
print(model.attrib)

It prints:

{'Id': '2', 'Name': 'fooname', 'Description': 'foo', 'Filter': 'f'}

Note the use of .attrib to access the element attributes.