I see a number of questions on SO asking about ways to convert XML to JSON, but I'm interested in going the other way. Is there a python library for converting JSON to XML?
Edit: Nothing came back right away, so I went ahead and wrote a script that solves this problem.
Python already allows you to convert from JSON into a native dict (using json or, in versions < 2.6, simplejson), so I wrote a library that converts native dicts into an XML string.
https://github.com/quandyfactory/dict2xml
It supports int, float, boolean, string (and unicode), array and dict data types and arbitrary nesting (yay recursion).
I'll post this as an answer once 8 hours have passed.
Nothing came back right away, so I went ahead and wrote a script that solves this problem.
Python already allows you to convert from JSON into a native dict (using json or, in versions < 2.6, simplejson), so I wrote a library that converts native dicts into an XML string.
https://github.com/quandyfactory/dict2xml
It supports int, float, boolean, string (and unicode), array and dict data types and arbitrary nesting (yay recursion).
If you don't have such a package, you can try:
def json2xml(json_obj, line_padding=""):
result_list = list()
json_obj_type = type(json_obj)
if json_obj_type is list:
for sub_elem in json_obj:
result_list.append(json2xml(sub_elem, line_padding))
return "\n".join(result_list)
if json_obj_type is dict:
for tag_name in json_obj:
sub_obj = json_obj[tag_name]
result_list.append("%s<%s>" % (line_padding, tag_name))
result_list.append(json2xml(sub_obj, "\t" + line_padding))
result_list.append("%s</%s>" % (line_padding, tag_name))
return "\n".join(result_list)
return "%s%s" % (line_padding, json_obj)
For example:
s='{"main" : {"aaa" : "10", "bbb" : [1,2,3]}}'
j = json.loads(s)
print(json2xml(j))
Result:
<main>
<aaa>
10
</aaa>
<bbb>
1
2
3
</bbb>
</main>
Load it into a dict using json.loads then use anything from this question...
Serialize Python dictionary to XML
Use dicttoxml to convert JSON directly to XML
Installation
pip install dicttoxml
or
easy_install dicttoxml
In [2]: from json import loads
In [3]: from dicttoxml import dicttoxml
In [4]: json_obj = '{"main" : {"aaa" : "10", "bbb" : [1,2,3]}}'
In [5]: xml = dicttoxml(loads(json_obj))
In [6]: print(xml)
<?xml version="1.0" encoding="UTF-8" ?><root><main type="dict"><aaa type="str">10</aaa><bbb type="list"><item type="int">1</item><item type="int">2</item><item type="int">3</item></bbb></main></root>
In [7]: xml = dicttoxml(loads(json_obj), attr_type=False)
In [8]: print(xml)
<?xml version="1.0" encoding="UTF-8" ?><root><main><aaa>10</aaa><bbb><item>1</item><item>2</item><item>3</item></bbb></main></root>
For more information on dicttoxml
I found xmltodict to be useful. Looks like it was released after some of the posts here. https://pypi.org/project/xmltodict/
import xmltodict
import json
sample_json = {"note": {"to": "Tove", "from": "Jani", "heading": "Reminder", "body": "Don't forget me this weekend!"}}
#############
#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)
from json import loads
from dicttoxml import dicttoxml
s='{"main" : {"aaa" : "10", "bbb" : [1,2,3]}}'
xml = dicttoxml(loads(s))
Or if your data is stored in a pandas data.frame as mine often is:
df['xml'] = df['json'].apply(lambda s: dicttoxml(json.loads(s))
Related
I had being look for the answer left and right. Even stackoverflow only has 1 similar question, but the answer does not work in my case. I fail to validate the xml and keep getting this error:
"unable to select an element for decoding data, provide a valid 'path' argument."
My goal is converting the json data to xml with validation. Anyone has any idea?
Below is my simple code:
import xmlschema
import json
from xml.etree import ElementTree
my_xsd = '<?xml version="1.0"?><schema targetNamespace = "urn:oasis:names:tc:emergency:cap:1.2" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <element name="note" type="xs:string"/><element name="age" type="xs:integer"/> </schema>'
schema = xmlschema.XMLSchema(my_xsd)
#jdata = xmlschema.to_json(xml_document = """<note>this is a Note text</note>""", schema = schema)
#jsonData = json.dumps(jdata)
data = json.dumps({'note': 'this is a Note text','age':'5'})
#print (jdata)
#print (jsonData)
print(data)
xml = xmlschema.from_json(data, schema=schema)
ElementTree.dump(xml)
I requested help from xmlschema creator and it turns out I need to have extra parameters as:
from_json(jsonTxt ,schema = CAPSchema, preserve_root=True, namespaces={'': 'urn:oasis:names:tc:emergency:cap:1.2'})
Hey I know there is a solution for this in Java, I'm curious to know if anyone knows of a Python 3 solution for converting a JSON object or file into protobuf format. I would accept either or as converting to an object is trivial. Searching the stackoverflow site, I only found examples of protobuf->json, but not the other way around. There is one extremely old repo that may do this but it is in Python 2 and our pipeline is Python 3. Any help is as always, appreciated.
The library you're looking for is google.protobuf.json_format. You can install it with the directions in the README here. The library is compatible with Python >= 2.7.
Example usage:
Given a protobuf message like this:
message Thing {
string first = 1;
bool second = 2;
int32 third = 3;
}
You can go from Python dict or JSON string to protobuf like:
import json
from google.protobuf.json_format import Parse, ParseDict
d = {
"first": "a string",
"second": True,
"third": 123456789
}
message = ParseDict(d, Thing())
# or
message = Parse(json.dumps(d), Thing())
print(message.first) # "a string"
print(message.second) # True
print(message.third) # 123456789
or from protobuf to Python dict or JSON string:
from google.protobuf.json_format import MessageToDict, MessageToJson
message_as_dict = MessageToDict(message)
message_as_dict['first'] # == 'a string'
message_as_dict['second'] # == True
message_as_dict['third'] # == 123456789
# or
message_as_json_str = MessageToJson(message)
The documentation for the json_format module is here.
Here is a much simpler way by using xia-easy-proto module. No need to pre-define anything.
pip install xia-easy-proto
And then
from xia_easy_proto import EasyProto
if __name__ == '__main__':
songs = {"composer": {'given_name': 'Johann', 'family_name': 'Pachelbel'},
"title": 'Canon in D',
"year": [1680, 1681]}
song_class, song_payload = EasyProto.serialize(songs)
print(song_class) # It is the message class
print(song_payload) # It is the serialized message
I need to add a $ symbol before the { on each line. how can I do it in python,
Problem: Using python I am reading all the API endpoint from the JSON file before I pass those API endpoints, I need to append a $ symbol just before to the open parenthesis {
Below is the code reads the API endpoint name from JSON file and prints.
import json
with open("example.json", "r") as reads: # Reading all the API endpoints from json file.
data = json.load(reads)
print(data['paths'].items())
for parameters, values in data['paths'].items():
print(parameters)
From the above code, I need to go further to achieve adding a $ symbol next to { before printing it.
Below list i get by reading the json file using python:
/API/{id}/one
/{two}/one/three
/three/four/{five}
Expected is:
/API/${id}/one
/${two}/one/three
/three/four/${five}
You could use .replace().
>>> obj="""
... /API/{id}/one
... /{two}/one/three
... /three/four/{five}
... """
>>> newobj = obj.replace('{','${')
>>> print(newobj)
/API/${id}/one
/${two}/one/three
/three/four/${five}
You Can use re library.
for parameters, values in data['paths'].items():
print(re.sub('{', '${', parameters))
For more info on re, Go through the doc. https://docs.python.org/3/library/re.html, It's a very helpful module.
I have a Python3 script that takes an input HTML template and populates some data using this JSON and creates an output HTML.
Python Script -
with open('./jsonInp.json') as jsonFile:
jsonData = json.load(jsonFile)
inp_f = open('brandedTemplate.html', 'r+')
htmlInp = inp_f.read().format(links = jsonData['links'])
My JSON File -
{
"links" : {
"one" : "www.one.com",
"two" : "www.two.com",
}
}
Now using this in the input HTML like :
...
<a href={links.one}></a>
...
But this doesn't work. Neither does links['one'].
The JSON loading and everything works fine. I am also able to use arrays from .format function. Just can't find how to use this object anywhere. From type(jsonData['links']), I know its a Python dict.
Is there a way to use this in a html template?
Your jsonData variable is a python dict. To access values in the format mini language you need to use {my_dict[my_key]}. Note that the key is not enclosed in quotes.
To fix your example, the html input should be as follow:
...
<a href={links[one]}></a>
...
According to [Python]: Format examples, you should use (templates like):
<a href={links[one]}></a>
as html format specifier (since [Python]: json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw) returns a dict).
Example:
>>> json_dict
{'links': {'one': 'www.one.com', 'two': 'www.two.com'}}
>>> href_text
'<a href={links[one]}></a>'
>>> href_text.format(links=json_dict["links"])
'<a href=www.one.com></a>'
I have this String that I need to pass into a REST request
{"notification":{"tag":"MyTag"}}
I'm trying to turn into an object using the JSON module in python.
This is my attempt so far
import json
obj = json.dumps([{'notification': ('{tag : MyTag}')}])
But it isn't parsed correctly so the REST request won't work. Anyone have any ideas?
Just dump your dictionary as is, replace:
obj = json.dumps([{'notification': ('{tag : MyTag}')}])
with:
obj = json.dumps({"notification": {"tag": "MyTag"}})