Reputation: 21
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
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
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
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
Reputation: 10917
from json import load
from dicttoxml import dicttoxml
...
xml = dicttoxml(load(input_var))
then save the xml to a file
Upvotes: 1