Search code examples
pythonxmlelementtreegraphml

Appending multiple elements with etree, how to write each element on new line?


I am adding some elements to some nodes in a a graphml file using Python and etree. I have two lists of strings with some data which I want to write to my .graphml file. I have managed to do this but when using the .append() function it writes the two new elements on the same line. Is there a good way to get a line separation between these new elements while writing them in the same loop?

I have the following dataset:

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns">
  <node id="node1">
    <data key="label">node1</data>
    <data key="degree">6</data>
  </node>
  <node id="node2">
    <data key="label">node2</data>
    <data key="degree">32</data>
  </node>
  <node id="node3">
    <data key="label">node3</data>
    <data key="degree">25</data>
  </node>
</graphml>

and two lists containing years:

lastActive["2013","2014","2015"]
lastRelated["2012","2014","2011"]

Using the following code to append the lists as elements in the dataset:

for node in root:

    #checks if correct node
    for index, i in enumerate(nameOfNode):
        if i == node[0].text:

            #create and add lastRelated element
            lastRelated = Element('data')
            lastRelated.set('key', 'lastRelated')
            node.append(lastRelated)
            lastRelated.text = lastRelated[index]

            #create and add lastActive element
            lastActive = Element('data')
            lastActive.set('key', 'lastActive')
            node.append(lastActive)
            lastActive.text = lastActive[index]

            updatedText = etree.tostring(node)

            #write to file
            file = open('dataset.graphml', 'wb')
            file.write(updatedText)
            file.close()

The following results are:

  <node id="node1">
  <data key="label">node1</data>
  <data key="degree">6</data>
  <data key="lastActive">2015</data><data key="lastRelated">2011</data></node>

I would like it to be structured as:

  <node id="node1">
  <data key="label">node1</data>
  <data key="degree">6</data>
  <data key="lastActive">2015</data>
  <data key="lastRelated">2011</data>
  </node>

Anyone got a solution for this?


Solution

  • You should be able to get the wanted output by providing a suitable value for the tail property on the new elements. The tail is text that comes after an element's end tag and before the following element's start tag.

    ...
    
    thetail = "\n  "
    lastRelated.tail = thetail
    lastActive.tail = thetail
    
    updatedText = etree.tostring(node)
    
    ...