Jennifer
Jennifer

Reputation: 19

How to access parent attribute of an xml tag?

I want to extract the name from 's text, only if its parent attribute is "enabled=true" in . I am not able to code this condition. Help will be appreciated. Thank you.

I am extracting names from 'Argument.name' using

-- for a in root.findall('.//stringProp[@name="Argument.name"]')

I am extracting values from 'Argument.value' using -- for b in root.findall('.//stringProp[@name="Argument.name"]..stringProp[@name="Argument.value"]')

I have tried something like this: for b in root.findall('.//*[@enabled="true]..//stringProp[@name="Argument.value"]')


<Arguments enabled="true" guiclass="ArgumentsPanel" testclass="Arguments" testname="Network Variables">
    <collectionProp name="Arguments.arguments">
        <elementProp elementType="Argument" name="ir-ip-address">
            <stringProp name="Argument.name">ir-ip-address</stringProp>
            <stringProp name="Argument.value">10.97.57.164</stringProp>
            <stringProp name="Argument.desc">ISP IP address</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
         </elementProp>

         <elementProp elementType="Argument" name="ir-gui-port">
             <stringProp name="Argument.name">ir-gui-port</stringProp>
             <stringProp name="Argument.value">8001</stringProp>
             <stringProp name="Argument.desc">ISP GUI port</stringProp>
             <stringProp name="Argument.metadata">=</stringProp>
         </elementProp>
      </collectionProp>
</Arguments>

<Arguments enabled="false" guiclass="ArgumentsPanel" testclass="Arguments" testname="Network Variables">
    <collectionProp name="Arguments.arguments">
        <elementProp elementType="Argument" name="ir-ip-address">
              <stringProp name="Argument.name">ir-ip-address</stringProp>
              <stringProp name="Argument.value">10.97.57.164</stringProp>
              <stringProp name="Argument.desc">ISP IP address</stringProp>
              <stringProp name="Argument.metadata">=</stringProp>
        </elementProp>

        <elementProp elementType="Argument" name="ir-gui-port">
            <stringProp name="Argument.name">ir-gui-port</stringProp>
            <stringProp name="Argument.value">8001</stringProp>
            <stringProp name="Argument.desc">ISP GUI port</stringProp>
            <stringProp name="Argument.metadata">=</stringProp>
        </elementProp>
    </collectionProp>
</Arguments>

Upvotes: 0

Views: 59

Answers (1)

abdusco
abdusco

Reputation: 11131

Here you go:

(Note that I've wrapped <Argument>s inside a <root>)

from xml.etree import ElementTree as ET
from xml.etree.ElementTree import ElementTree

if __name__ == '__main__':
    raw_xml = '''
    <root>
    <Arguments enabled="true" guiclass="ArgumentsPanel" testclass="Arguments" testname="Network Variables">
        <collectionProp name="Arguments.arguments">
            <elementProp elementType="Argument" name="ir-ip-address">
                <stringProp name="Argument.name">ir-ip-address</stringProp>
                <stringProp name="Argument.value">10.97.57.164</stringProp>
                <stringProp name="Argument.desc">ISP IP address</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>

             <elementProp elementType="Argument" name="ir-gui-port">
                 <stringProp name="Argument.name">ir-gui-port</stringProp>
                 <stringProp name="Argument.value">8001</stringProp>
                 <stringProp name="Argument.desc">ISP GUI port</stringProp>
                 <stringProp name="Argument.metadata">=</stringProp>
             </elementProp>
          </collectionProp>
    </Arguments>

    <Arguments enabled="false" guiclass="ArgumentsPanel" testclass="Arguments" testname="Network Variables">
        <collectionProp name="Arguments.arguments">
            <elementProp elementType="Argument" name="ir-ip-address">
                  <stringProp name="Argument.name">ir-ip-address</stringProp>
                  <stringProp name="Argument.value">10.97.57.164</stringProp>
                  <stringProp name="Argument.desc">ISP IP address</stringProp>
                  <stringProp name="Argument.metadata">=</stringProp>
            </elementProp>

            <elementProp elementType="Argument" name="ir-gui-port">
                <stringProp name="Argument.name">ir-gui-port</stringProp>
                <stringProp name="Argument.value">8001</stringProp>
                <stringProp name="Argument.desc">ISP GUI port</stringProp>
                <stringProp name="Argument.metadata">=</stringProp>
            </elementProp>
        </collectionProp>
    </Arguments>
    </root>
    '''

    root: ElementTree = ET.fromstring(raw_xml)
    for arg in root.findall('Arguments[@enabled="true"]'):
        argname = arg.find('.//stringProp[@name="Argument.name"]').text
        argval = arg.find('.//stringProp[@name="Argument.value"]').text
        print(argname, argval)

which prints:

ir-ip-address 10.97.57.164

Upvotes: 2

Related Questions