0

I wish to convert several Json entries to XML.

My Json file looks like this

{
    "list": [
         {"id":1,"author":"abc","title":"xyz"},
         {"id":2,"author":"def","title":"mno"}
    ]
}

The code I'm using right now :

import json as j
import xml.etree.cElementTree as e
with open('data.json') as data_file:    
    data = j.load(data_file)
for obj in data['list']:
    r = e.Element("sequence")
    e.SubElement(r,"id").text = obj["id"]
    e.SubElement(r,"submitter").text = obj["submitter"]
    e.SubElement(r,"authors").text = str(obj["authors"])
    e.SubElement(r,"title").text = str(obj["title"])   
    a = e.ElementTree(r)
    a.write("json_to_xml.xml")

I need something like a.append() instead of a.write() since it's being overwritten every time and I get only 1 result at the end. Is there anything like that?

I need the output to look like this

<sequence>
<id>1</id>
<author>abc</author>
<title>xyz</title>
</sequence>
<sequence>
<id>2</id>
<author>def</author>
<title>mno</title>
</sequence>

1 Answers1

0

Move the writing outside the loop.

>>> from xml.etree import ElementTree as ET
>>> import json
>>> from io import BytesIO
>>>
>>> data = '''\
... {
...     "list": [
...          {"id":1,"author":"abc","title":"xyz"},
...          {"id":2,"author":"def","title":"mno"}
...     ]
... }
... '''
>>>
>>> d = json.loads(data)
>>>
>>> r = ET.Element("sequence")
>>> for obj in d['list']:
...     ET.SubElement(r, "id").text = str(obj["id"])
...     ET.SubElement(r, "author").text = str(obj["author"])
...     ET.SubElement(r, "title").text = str(obj["title"])
...
>>>
>>> a = ET.ElementTree(r)
>>> ET.indent(a) # new in 3.9
>>> f = BytesIO()
>>> a.write(f)
>>>
>>> print(f.getvalue().decode('UTF8'))
<sequence>
  <id>1</id>
  <author>abc</author>
  <title>xyz</title>
  <id>2</id>
  <author>def</author>
  <title>mno</title>
</sequence>
>>>

If you have python 3.9, you can use ET.indent.

Justin Ezequiel
  • 5,254
  • 2
  • 11
  • 14