diff --git a/ToXml.py b/ToXml.py new file mode 100644 index 0000000..04d2453 --- /dev/null +++ b/ToXml.py @@ -0,0 +1,204 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -* + +""" + _\|/_ + (o o) + +----oOO-{_}-OOo-------+ + | | + |http://www.quennec.com| + +----------------------+ +""" + +from pprint import pprint +from xml.dom import minidom +from string import ascii_uppercase +import os, sys, re, json, os + +class ToXml(): + + class __MyError(Exception): + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + + def __init__(self): + self.xml = "" + self.dom = None + + def __dicttoxml(self, kw): + xml = [] + t = type(kw) + + if t is dict: + for x in kw: + nodename = x.split('@')[0].strip().replace(" ", "_") + try: + attribut = ' '.join(['{0}="{1}"'.format(y.split('=')[0], \ + y.split('=')[1]) for y in x.split('@')[1].split('&')]) + except: + attribut = '' + if nodename[0].isnumeric(): + attribut += ' v="' + nodename + '"' + nodename = 'XMLNODE' + node = "<" + "{0} {1}".format(nodename, attribut).strip() + ">" + if type(kw[x]) is list: + for y in kw[x]: + xml.append(node) + xml.append(self.__dicttoxml(y)) + xml.append("".format(nodename)) + else: + xml.append(node) + xml.append(self.__dicttoxml(kw[x])) + xml.append("".format(nodename)) + return "".join(xml) + + return "{0}".format(str(kw)) + + def __todom(self): + try: + self.dom = minidom.parseString(self.xml) + except: + + self.xml = "" + self.xml + "" + try: + self.dom = minidom.parseString(self.xml) + except Exception as e: + print(e) + print("Unknown error encountered during the treatment.") + sys.exit(1) + + def fromjson(self, jsonfile): + """ + Converting from a JSON file + """ + if(os.path.exists(jsonfile)): + with open(jsonfile, mode='r', encoding='UTF8') as f: + try: + j = json.load(f) + except Exception as e: + print(e) + print("Unknown error encountered into the JSON file.") + sys.exit(1) + + self.__main(j) + + else: + print("The file {0} does not exist !".format(jsonfile)) + sys.exit(1) + + def fromjsons(self, jsonstr): + """ + Converting from a JSON string + """ + if type(jsonstr) is str: + try: + j = json.loads(jsonstr) + except Exception as e: + print(e) + print("Unknown error encountered into the JSON string.") + sys.exit(1) + + self.__main(j) + + else: + print("The argument does not a string !") + sys.exit(1) + + def fromdict(self, d): + """ + Converting from a Dictionnary (Python's dict type) + """ + if type(d) is dict: + self.__main(d) + else: + print("The argument does not a Python's dict type !") + sys.exit(1) + + def __main(self, j): + self.xml = self.__dicttoxml(j) + self.__todom() + + def __repr__(self): + return repr(self.dom.toprettyxml()) + + def __str__(self): + return str(self.dom.toprettyxml()) + + def tofile(self, filename, overwrite=False): + try: + if filename.strip() is None or filename.strip() == '': + raise self.__MyError('The filename must not be blank.') + folder = os.path.dirname(filename) + if not os.path.exists(folder): + raise self.__MyError("The indicated folder '{0}' does not exist.".format(folder)) + if os.path.exists(filename) and not overwrite: + raise self.__MyError("The indicated filename '{0}' \ +already exist in the folder '{1}'.".format(os.path.basename(filename), folder)) + with open(filename, 'w') as f: + print(self.topretty(), file=f) + + except self.__MyError as e: + print(e.value) + sys.exit(1) + except Exception as e: + print(e) + sys.exit(1) + + def topretty(self): + """ + assign the XML content to a variable + myxmlstr = self.topretty() + """ + return self.dom.toprettyxml() + + def example(self): + aJson = """{ + "menu@id=file&value=File": { + "popup": { + "menuitem": [ + { "value": "New", "onclick": "CreateNewDoc()" }, + { "value": "Open", "onclick": "OpenDoc()" }, + { "value": "Close", "onclick": "CloseDoc()" } + ], + "nodeNameStartWithValueNumeric": { + "001": "1", + "010@id=5": "2", + "100": "4" + } + } + } +}""" + print("") + print("For information, if the key value start with numeric characters,") + print("the key is replaced by 'XMLNODE' and the key value") + print("is indicated as attribute value named 'v'.") + print("See example below (see key 'nodeNameStartWithValueNumeric').") + print("") + print("Example from the JSON string:\n\n\t{0}".format('>>> aJson = """'+aJson+'"""')) + print("") + print("Let's create a new object 'ex' from the class 'ToXml'.\n\n\t{0}".format(">>> ex = ToXml()")) + print("") + print("Let's parse the JSON string with the function 'fromjsons'.\n\n\t{0}".format(">>> ex.fromjsons(aJson)")) + print("") + print("Finally, let's display the result.\n\n\t{0}".format(">>> print(ex)")) + print("") + ex = ToXml() + ex.fromjsons(aJson) + print(ex) + ex = None + +if __name__ == '__main__': + if not sys.stdin.isatty(): + foo = ToXml() + foo.fromjsons(sys.stdin.read()) + print(foo) + foo = None + else: + print("Use this class with a pipe command") + print("or with a import in a Python script.") + print("") + print('echo \'{"foo": {"bar": "tata", "titi": "toto"}}\' | python3 ToXml.py') + print("or") + print("curl \"http://api.geonames.org/timezoneJSON?formatted=true&lat=47.01&lng=10.2&username=demo&style=full\" -o - -s | python3 ToXml.py ") \ No newline at end of file