Search code examples
pythonxmlxml-generation

writing xml to file python multiple times


I seem to be stuck. I am trying to get multiple iterations of the xml that is generated from my python code. It only writes the latest iteration to file.

Here is my code:

import xml.etree.cElementTree as ET
from random import randint

i=5
while i>-4:
  event = ET.Element("event")
  event.set("class", "rer")
  event.set("id", "EV_%d" % (i))
  event.set("date", "${ev_d}")

  loc = ET.SubElement(event, "loc")
  flir = ET.SubElement(loc, "flir")

  de = ET.SubElement(flir, "de")
  de.set("dist", "km")
  de.set("val", "%d" % (randint(0,2)))

  i -=1   

  tree = ET.ElementTree(event)
  tree.write("test.xml")

What I get:

<event class="rer" date="${ev_d}" id="EV_-3">
  <loc>
    <flir>
      <de dist="km" val="0" />
    </flir>
  </loc>
</event>

What I want in the output file:

<event class="rer" date="${ev_d}" id="EV_5">
  <loc>
    <flir>
      <de dist="km" val="0" />
    </flir>
  </loc>
</event>
<event class="rer" date="${ev_d}" id="EV_4">
  <loc>
    <flir>
      <de dist="km" val="0" />
    </flir>
  </loc>
</event>
<event class="rer" date="${ev_d}" id="EV_3">
  <loc>
    <flir>
      <de dist="km" val="0" />
    </flir>
  </loc>
</event>

Thanks in advance for your help.

Regards, merit_2


Solution

  • As @jwodder pointed out, your proposed output is not valid XML. Your options are to fix that or get around it. Since you mentioned that this is only a component, here's a way to do it if you have a parent element that each <event> will be nested under.

    import xml.etree.cElementTree as ET
    from random import randint
    
    parent = ET.Element("parent")
    tree = ET.ElementTree(parent)
    
    i=5
    while i>-4:
        event = ET.Element("event")
        event.set("class", "rer")
        event.set("id", "EV_%d" % (i))
        event.set("date", "${ev_d}")
    
        loc = ET.SubElement(event, "loc")
        flir = ET.SubElement(loc, "flir")
    
        de = ET.SubElement(flir, "de")
        de.set("dist", "km")
        de.set("val", "%d" % (randint(0,2)))
    
        i -=1   
    
        parent.append(event)
    
    tree.write("test.xml")
    

    Here I added the parent element and append-ed event to the parent, then wrote the parent tree out to file at the end.

    Output:

    <parent>
      <event class="rer" date="${ev_d}" id="EV_5">
        <loc>
          <flir>
            <de dist="km" val="1" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_4">
        <loc>
          <flir>
            <de dist="km" val="2" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_3">
        <loc>
          <flir>
            <de dist="km" val="2" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_2">
        <loc>
          <flir>
            <de dist="km" val="1" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_1">
        <loc>
          <flir>
            <de dist="km" val="2" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_0">
        <loc>
          <flir>
            <de dist="km" val="0" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_-1">
        <loc>
          <flir>
            <de dist="km" val="2" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_-2">
        <loc>
          <flir>
            <de dist="km" val="0" />
          </flir>
        </loc>
      </event>
      <event class="rer" date="${ev_d}" id="EV_-3">
        <loc>
          <flir>
            <de dist="km" val="2" />
          </flir>
        </loc>
      </event>
    </parent>