ElementTree find returns 'None'?

Viewed 690

I'm using ElementTree with Python to parse an XML file.

This is the sample of XML file I'm trying to parse:

<?xml version="1.0" encoding="UTF-8"?>
<objects fpmi.archive.type="components" framework.version="7.9.8.2018060714" fpmi.version="9.9.8.0" timestamp="Thu Sep 27 15:00:19 CEST 2018">
  <arraylist len="0"/>
<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>10.0;10.0;26.0;14.0</r2dd>
    <str>X123_C61023</str>
    <lc>10.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>X123_X123_C61023</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>[network]premium/aw1/tags/monitors</str>
  </c-c>
</c>

console always return None .

My code:

import xml.etree.ElementTree as ET

mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

for x in myroot.findall('c'):
        p2df=x.find('p2df')
        r2dd=x.find('r2dd')
        print(p2df, r2dd)

Please help..

2 Answers

Element.findall() searches only elements with a tag which are direct children of the current element. The same is happening with find() but find() returns the first match. So first you need to traverse to c-comm, to find the p2df element, and since objects is the root node, you first traverse to c, then c-comm to then find the objects. See below snippet.

import xml.etree.ElementTree as ET

mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

cNode = myroot.find('c')
for x in cNode.findall('c-comm'):
  p2df=x.find('p2df')
  r2dd=x.find('r2dd')
  print(p2df.text, r2dd.text)

Your example xml is not well formed. You need a closing </objects> tag at the end for the parser to be able to read the file.

thanks for your help its working now. but I did it in a different way also .:

import xml.etree.ElementTree as ET

mytree = ET.parse('sample.xml')
myroot = mytree.getroot()

interface = myroot.getchildren()[1].getchildren()[0]
print(interface)

r2dd = interface.getchildren()[1]
print(r2dd.text)

str = interface.getchildren()[2]
print(str.text)

now i have a next problem how to add values for other items in this xml? i mean next items, this is file :

<?xml version="1.0" encoding="UTF-8"?>
<objects fpmi.archive.type="components" framework.version="7.9.8.2018060714" fpmi.version="9.9.8.0" timestamp="Thu Sep 27 15:00:19 CEST 2018">
  <arraylist len="0"/>
<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>10.0;10.0;26.0;14.0</r2dd>
    <str>XXY_Y61021</str>
    <lc>10.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>XXY_Y6102_C61021</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>XXXYYYYY</str>
  </c-c>
</c>

<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>60.0;10.0;26.0;14.0</r2dd>
    <str>XXY_Y61022</str>
    <lc>60.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>XXY_Y6102_C61022</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>XXXYYYYY</str>
  </c-c>
</c>

<c cls="com.inductiveautomation.factorypmi.application.components.template.TemplateHolder">
  <c-comm>
    <p2df>26.0;14.0</p2df>
    <r2dd>110.0;10.0;26.0;14.0</r2dd>
    <str>XXY_Y61021</str>
    <lc>110.0;10.0;16;0;0.7058824;1.3333334</lc>
  </c-comm>
  <c-c m="setParameterValues" s="1;java.util.Map">
    <o cls="java.util.HashMap">
      <o-c m="put" s="2;O;O">
        <str>tagPath</str>
        <str>XXY_Y6102_C61021</str>
      </o-c>
    </o>
  </c-c>
  <c-c m="setTemplatePath" s="1;str">
    <str>XXXYYYYY</str>
  </c-c>
</c>

yes this example has missing closure for object but on pc i have a full file

Related