Commit 4c1c3ce81ad16618adbfc19c3cf78097acb8b583

Authored by ronan
1 parent ddcbdc4f9f
Exists in master

added

Showing 1 changed file with 204 additions and 0 deletions

  1 +#!/usr/bin/python3
  2 +# -*- coding: utf-8 -*
  3 +
  4 +"""
  5 + _\|/_
  6 + (o o)
  7 + +----oOO-{_}-OOo-------+
  8 + | |
  9 + |http://www.quennec.com|
  10 + +----------------------+
  11 +"""
  12 +
  13 +from pprint import pprint
  14 +from xml.dom import minidom
  15 +from string import ascii_uppercase
  16 +import os, sys, re, json, os
  17 +
  18 +class ToXml():
  19 +
  20 + class __MyError(Exception):
  21 + def __init__(self, value):
  22 + self.value = value
  23 + def __str__(self):
  24 + return repr(self.value)
  25 +
  26 + def __init__(self):
  27 + self.xml = ""
  28 + self.dom = None
  29 +
  30 + def __dicttoxml(self, kw):
  31 + xml = []
  32 + t = type(kw)
  33 +
  34 + if t is dict:
  35 + for x in kw:
  36 + nodename = x.split('@')[0].strip().replace(" ", "_")
  37 + try:
  38 + attribut = ' '.join(['{0}="{1}"'.format(y.split('=')[0], \
  39 + y.split('=')[1]) for y in x.split('@')[1].split('&')])
  40 + except:
  41 + attribut = ''
  42 + if nodename[0].isnumeric():
  43 + attribut += ' v="' + nodename + '"'
  44 + nodename = 'XMLNODE'
  45 + node = "<" + "{0} {1}".format(nodename, attribut).strip() + ">"
  46 + if type(kw[x]) is list:
  47 + for y in kw[x]:
  48 + xml.append(node)
  49 + xml.append(self.__dicttoxml(y))
  50 + xml.append("</{0}>".format(nodename))
  51 + else:
  52 + xml.append(node)
  53 + xml.append(self.__dicttoxml(kw[x]))
  54 + xml.append("</{0}>".format(nodename))
  55 + return "".join(xml)
  56 +
  57 + return "{0}".format(str(kw))
  58 +
  59 + def __todom(self):
  60 + try:
  61 + self.dom = minidom.parseString(self.xml)
  62 + except:
  63 +
  64 + self.xml = "<XML>" + self.xml + "</XML>"
  65 + try:
  66 + self.dom = minidom.parseString(self.xml)
  67 + except Exception as e:
  68 + print(e)
  69 + print("Unknown error encountered during the treatment.")
  70 + sys.exit(1)
  71 +
  72 + def fromjson(self, jsonfile):
  73 + """
  74 + Converting from a JSON file
  75 + """
  76 + if(os.path.exists(jsonfile)):
  77 + with open(jsonfile, mode='r', encoding='UTF8') as f:
  78 + try:
  79 + j = json.load(f)
  80 + except Exception as e:
  81 + print(e)
  82 + print("Unknown error encountered into the JSON file.")
  83 + sys.exit(1)
  84 +
  85 + self.__main(j)
  86 +
  87 + else:
  88 + print("The file {0} does not exist !".format(jsonfile))
  89 + sys.exit(1)
  90 +
  91 + def fromjsons(self, jsonstr):
  92 + """
  93 + Converting from a JSON string
  94 + """
  95 + if type(jsonstr) is str:
  96 + try:
  97 + j = json.loads(jsonstr)
  98 + except Exception as e:
  99 + print(e)
  100 + print("Unknown error encountered into the JSON string.")
  101 + sys.exit(1)
  102 +
  103 + self.__main(j)
  104 +
  105 + else:
  106 + print("The argument does not a string !")
  107 + sys.exit(1)
  108 +
  109 + def fromdict(self, d):
  110 + """
  111 + Converting from a Dictionnary (Python's dict type)
  112 + """
  113 + if type(d) is dict:
  114 + self.__main(d)
  115 + else:
  116 + print("The argument does not a Python's dict type !")
  117 + sys.exit(1)
  118 +
  119 + def __main(self, j):
  120 + self.xml = self.__dicttoxml(j)
  121 + self.__todom()
  122 +
  123 + def __repr__(self):
  124 + return repr(self.dom.toprettyxml())
  125 +
  126 + def __str__(self):
  127 + return str(self.dom.toprettyxml())
  128 +
  129 + def tofile(self, filename, overwrite=False):
  130 + try:
  131 + if filename.strip() is None or filename.strip() == '':
  132 + raise self.__MyError('The filename must not be blank.')
  133 + folder = os.path.dirname(filename)
  134 + if not os.path.exists(folder):
  135 + raise self.__MyError("The indicated folder '{0}' does not exist.".format(folder))
  136 + if os.path.exists(filename) and not overwrite:
  137 + raise self.__MyError("The indicated filename '{0}' \
  138 +already exist in the folder '{1}'.".format(os.path.basename(filename), folder))
  139 + with open(filename, 'w') as f:
  140 + print(self.topretty(), file=f)
  141 +
  142 + except self.__MyError as e:
  143 + print(e.value)
  144 + sys.exit(1)
  145 + except Exception as e:
  146 + print(e)
  147 + sys.exit(1)
  148 +
  149 + def topretty(self):
  150 + """
  151 + assign the XML content to a variable
  152 + myxmlstr = self.topretty()
  153 + """
  154 + return self.dom.toprettyxml()
  155 +
  156 + def example(self):
  157 + aJson = """{
  158 + "menu@id=file&value=File": {
  159 + "popup": {
  160 + "menuitem": [
  161 + { "value": "New", "onclick": "CreateNewDoc()" },
  162 + { "value": "Open", "onclick": "OpenDoc()" },
  163 + { "value": "Close", "onclick": "CloseDoc()" }
  164 + ],
  165 + "nodeNameStartWithValueNumeric": {
  166 + "001": "1",
  167 + "010@id=5": "2",
  168 + "100": "4"
  169 + }
  170 + }
  171 + }
  172 +}"""
  173 + print("")
  174 + print("For information, if the key value start with numeric characters,")
  175 + print("the key is replaced by 'XMLNODE' and the key value")
  176 + print("is indicated as attribute value named 'v'.")
  177 + print("See example below (see key 'nodeNameStartWithValueNumeric').")
  178 + print("")
  179 + print("Example from the JSON string:\n\n\t{0}".format('>>> aJson = """'+aJson+'"""'))
  180 + print("")
  181 + print("Let's create a new object 'ex' from the class 'ToXml'.\n\n\t{0}".format(">>> ex = ToXml()"))
  182 + print("")
  183 + print("Let's parse the JSON string with the function 'fromjsons'.\n\n\t{0}".format(">>> ex.fromjsons(aJson)"))
  184 + print("")
  185 + print("Finally, let's display the result.\n\n\t{0}".format(">>> print(ex)"))
  186 + print("")
  187 + ex = ToXml()
  188 + ex.fromjsons(aJson)
  189 + print(ex)
  190 + ex = None
  191 +
  192 +if __name__ == '__main__':
  193 + if not sys.stdin.isatty():
  194 + foo = ToXml()
  195 + foo.fromjsons(sys.stdin.read())
  196 + print(foo)
  197 + foo = None
  198 + else:
  199 + print("Use this class with a pipe command")
  200 + print("or with a import in a Python script.")
  201 + print("")
  202 + print('echo \'{"foo": {"bar": "tata", "titi": "toto"}}\' | python3 ToXml.py')
  203 + print("or")
  204 + print("curl \"http://api.geonames.org/timezoneJSON?formatted=true&lat=47.01&lng=10.2&username=demo&style=full\" -o - -s | python3 ToXml.py ")