Blame view

ToXml.py 6.45 KB
4c1c3ce81   ronan   added
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  #!/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("</{0}>".format(nodename))
                  else:
                      xml.append(node)
                      xml.append(self.__dicttoxml(kw[x]))
                      xml.append("</{0}>".format(nodename))
              return "".join(xml)
  
          return "{0}".format(str(kw))
  
      def __todom(self):
          try:
              self.dom = minidom.parseString(self.xml)
          except:
  
              self.xml = "<XML>" + self.xml + "</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:
  
  \t{0}".format('>>> aJson = """'+aJson+'"""'))
          print("")
          print("Let's create a new object 'ex' from the class 'ToXml'.
  
  \t{0}".format(">>> ex = ToXml()"))
          print("")
          print("Let's parse the JSON string with the function 'fromjsons'.
  
  \t{0}".format(">>> ex.fromjsons(aJson)"))
          print("")
          print("Finally, let's display the result.
  
  \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 ")