Anmol
Anmol

Reputation: 21

JSON to XML File using Python

I am trying to convert one big JSON file to a XML file. Below are the two lines which i took out from a big JSON. I am trying to create a root node for every INVENTORY_SEQ_ID present in this file:

[{"INVENTORY_SEQ_ID":4577494,"GROUP_NBR":8605548,"SEQ_NBR":300,"FACILITY_CODE":"OCALADC","COMPANY_CODE":"AMES"},
{"INVENTORY_SEQ_ID":4577495,"GROUP_NBR":8605548,"SEQ_NBR":301,"FACILITY_CODE":"OCALADC","COMPANY_CODE":"AMES"}]

I have written below code (I am just a beginner in this field) and it works if there is only one Row in the JSON file. It throw an error if there are more thab one.

import json as j
with open("invdata.json") as input_var:
 d=j.load(input_var)
import xml.etree.cElementTree as e
r=e.Element("InvHead")
e.SubElement(r,"INVENTORY_SEQ_ID").text = str(d["INVENTORY_SEQ_ID"])
e.SubElement(r,"GROUP_NBR").text = str(d["GROUP_NBR"])
e.SubElement(r,"SEQ_NBR").text = str(d["SEQ_NBR"])
e.SubElement(r,"FACILITY_CODE").text = d["FACILITY_CODE"]
e.SubElement(r,"COMPANY_CODE").text = d["COMPANY_CODE"]
a=e.ElementTree(r)
a.write("output.xml")

Any help is deeply appreciated.

Thanks ANmol

Upvotes: 2

Views: 4506

Answers (4)

Jortega
Jortega

Reputation: 3790

I found xmltodict to be useful for this task. See https://pypi.org/project/xmltodict/

import xmltodict
import json
sample_json = {
    "document":{
    "firstName": "Jane",
    "lastName": "Doe",
    "hobbies": ["running", "sky diving", "singing"],
    "age": 35,
    "children": [
        {
            "firstName": "Alice",
            "age": 6
        },
        {
            "firstName": "Bob",
            "age": 8
        }
    ]}

}
#############
#json to xml
#############
json_to_xml = xmltodict.unparse(sample_json)
print(json_to_xml)
#############
#xmlto json
#############
x_to_j_dict = xmltodict.parse(json_to_xml)
x_to_j_string = json.dumps(x_to_j_dict)
back_to_json = json.loads(x_to_j_string)
print(back_to_json)

Upvotes: 0

Leon95
Leon95

Reputation: 73

Here is my attempt: I needed the dict Keys to become the Tag Names.

def to_xml(values):
    result = ""
    # this works only for text and int values.
    # implement your own case for other types.
    if isinstance(values, str) or  isinstance(values, int):
        return values
    elif isinstance(values, dict):
        for key in values:
            result += "<" + key + ">" + str(to_xml(values[key])) + "</" + key + ">"
        return result

Output:

>>> mydict = {"test":{"foo":"bar","number":1}}
>>> to_xml(mydict)
'<test><foo>bar</foo><number>1</number></test>'

If you need it as xml Object you can parse it again:

>>> from xml.dom import minidom
>>> minidom.parseString(to_xml(mydict))
<xml.dom.minidom.Document object at 0x7fdc3e9d1be0>

Upvotes: 1

Rahul Raj Purohit
Rahul Raj Purohit

Reputation: 161

When there is only one object json.load will return a dict, whereas for multiple entries it returns a list of dicts. So you can make your code work if you replace d["INVENTORY_SEQ_ID"] with d[i]["INVENTORY_SEQ_ID"], where i iterates over all your objects.

Instead you can try out this simpler approach

from json import load,loads
from dicttoxml import dicttoxml

with open("invdata.json") as input_var:
 d=load(input_var)
di = {"InvHead":d}
xm = dicttoxml(di)     #returns xm as <class 'bytes'> object

with open("output.xml", mode='wb') as out:  #opening in write-bytes mode 
    out.write(xm)

And the output XML being output.xml

Let me know if this works in your case.
RRP

Upvotes: 2

log0
log0

Reputation: 10917

from json import load
from dicttoxml import dicttoxml
...
xml = dicttoxml(load(input_var))

then save the xml to a file

Upvotes: 1

Related Questions