2

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

1

4 Answers 4

2

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

Sign up to request clarification or add additional context in comments.

Comments

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

then save the xml to a file

Comments

1

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>

Comments

0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.