Commit 4c1c3ce81ad16618adbfc19c3cf78097acb8b583
1 parent
ddcbdc4f9f
Exists in
master
added
Showing 1 changed file with 204 additions and 0 deletions
ToXml.py
View file @
4c1c3ce
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 ") |