1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module containing generic functions for creation and parsing of XML representations of Python objects."""
24
25
26 import numpy
27 from numpy import set_printoptions, array, inf, nan, ndarray, zeros
28 from re import search
29
30
31 set_printoptions(precision=15, threshold=nan)
32
33
34 import lib.arg_check
35 import lib.check_types
36 from lib.float import floatAsByteArray, packBytesAsPyFloat
37 from lib.errors import RelaxError
38
39
40 -def fill_object_contents(doc, elem, object=None, blacklist=[]):
41 """Place all simple python objects into the XML element namespace.
42
43 @param doc: The XML document object.
44 @type doc: xml.dom.minidom.Document instance
45 @param elem: The element to add all python objects to.
46 @type elem: XML element object
47 @keyword object: The python class instance containing the objects to add.
48 @type object: instance
49 @keyword blacklist: A list of object names to exclude.
50 @type blacklist: list of str
51 """
52
53
54 for name in dir(object):
55
56 if name in blacklist:
57 continue
58
59
60 if search("^_", name):
61 continue
62
63
64 if hasattr(object, '_mod_attr') and name not in object._mod_attr:
65 continue
66
67
68 sub_elem = doc.createElement(name)
69 elem.appendChild(sub_elem)
70
71
72 subobj = getattr(object, name)
73
74
75 object_to_xml(doc, sub_elem, value=subobj)
76
77
79 """Convert the node value to a python expression.
80
81 @param elem: The XML element.
82 @type elem: xml.dom.minidom.Element instance
83 """
84
85
86 val = elem.nodeValue.strip()
87
88
89 return eval(val)
90
91
93 """Convert the given value into an XML form.
94
95 @param doc: The XML document object.
96 @type doc: xml.dom.minidom.Document instance
97 @param elem: The element to add the Python objects to.
98 @type elem: XML element object
99 @keyword value: The Python object to convert.
100 @type value: anything
101 """
102
103
104 val_elem = doc.createElement('value')
105 elem.appendChild(val_elem)
106 val_elem.appendChild(doc.createTextNode(repr(value)))
107
108
109 if value == None:
110 py_type = 'None'
111 elif isinstance(value, bool):
112 py_type = 'bool'
113 elif isinstance(value, str):
114 py_type = 'str'
115 elif isinstance(value, float):
116 py_type = 'float'
117 elif isinstance(value, int):
118 py_type = 'int'
119 elif isinstance(value, list):
120 py_type = 'list'
121 elif isinstance(value, dict):
122 py_type = 'dict'
123 elif isinstance(value, ndarray):
124 py_type = repr(value.dtype)
125 else:
126 raise RelaxError("Unknown type for the value '%s'." % value)
127
128
129 elem.setAttribute('type', py_type)
130
131
132 if lib.check_types.is_float(value):
133 val_elem = doc.createElement('ieee_754_byte_array')
134 elem.appendChild(val_elem)
135 val_elem.appendChild(doc.createTextNode(repr(floatAsByteArray(value))))
136
137
138 elif (isinstance(value, list) or isinstance(value, ndarray)) and len(value) and lib.check_types.is_float(value[0]):
139
140 ieee_obj = []
141 conv = False
142 for i in range(len(value)):
143
144 if lib.check_types.is_float(value[i]):
145 ieee_obj.append(floatAsByteArray(value[i]))
146 conv = True
147
148
149 else:
150 ieee_obj.append(value)
151
152
153 if conv:
154
155 val_elem = doc.createElement('ieee_754_byte_array')
156 elem.appendChild(val_elem)
157
158
159 val_elem.appendChild(doc.createTextNode(repr(ieee_obj)))
160
161
162 elif py_type == 'dict':
163
164 ieee_obj = {}
165 conv = False
166 for key in list(value.keys()):
167 if lib.check_types.is_float(value[key]):
168 ieee_obj[key] = floatAsByteArray(value[key])
169 conv = True
170
171
172 if conv:
173
174 val_elem = doc.createElement('ieee_754_byte_array')
175 elem.appendChild(val_elem)
176
177
178 val_elem.appendChild(doc.createTextNode(repr(ieee_obj)))
179
180
181 elif lib.arg_check.is_float_matrix(value, raise_error=False):
182
183 ieee_obj = []
184 for i in range(len(value)):
185 ieee_obj.append([])
186 for j in range(len(value[i])):
187 ieee_obj[-1].append(floatAsByteArray(value[i][j]))
188
189
190 val_elem = doc.createElement('ieee_754_byte_array')
191 elem.appendChild(val_elem)
192
193
194 val_elem.appendChild(doc.createTextNode(repr(ieee_obj)))
195
196
197 -def xml_to_object(elem, base_object=None, set_fn=None, file_version=1, blacklist=[]):
198 """Convert the XML elements into python objects, and place these into the base object.
199
200 @param elem: The element to extract all python objects from.
201 @type elem: xml.dom.minidom.Element instance
202 @keyword base_object: The python class instance to place the objects into.
203 @type base_object: instance
204 @keyword set_fn: A function used to replace setattr for placing the object into the base
205 object.
206 @type set_fn: function
207 @keyword file_version: The relax XML version of the XML file.
208 @type file_version: int
209 @keyword blacklist: A list of object names to exclude.
210 @type blacklist: list of str
211 """
212
213
214 for node in elem.childNodes:
215
216 if node.localName == None:
217 continue
218
219
220 name = str(node.localName)
221
222
223 if name in blacklist:
224 continue
225
226
227 if file_version == 1:
228
229 ieee_array = node.getAttribute('ieee_754_byte_array')
230 if ieee_array:
231 value = packBytesAsPyFloat(eval(ieee_array))
232
233
234 else:
235 value = node_value_to_python(node.childNodes[0])
236
237
238 elif file_version == 2:
239
240 py_type = node.getAttribute('type')
241 if not search('dtype', py_type):
242 py_type = eval(py_type)
243
244
245 ieee_value = None
246 for sub_node in node.childNodes:
247
248 if sub_node.localName == 'value':
249 value = node_value_to_python(sub_node.childNodes[0])
250
251
252 if sub_node.localName == 'ieee_754_byte_array':
253 ieee_value = node_value_to_python(sub_node.childNodes[0])
254
255
256 if ieee_value:
257
258 if py_type == float:
259 value = packBytesAsPyFloat(ieee_value)
260
261
262 elif py_type == dict:
263 for key in ieee_value:
264 value[key] = packBytesAsPyFloat(ieee_value[key])
265
266
267 elif py_type == list:
268
269 for i in range(len(value)):
270
271 if isinstance(value[i], list) or isinstance(value[i], ndarray):
272 for j in range(len(value[i])):
273 value[i][j] = packBytesAsPyFloat(ieee_value[i][j])
274
275
276 else:
277 value[i] = packBytesAsPyFloat(ieee_value[i])
278
279
280 elif search('dtype', py_type):
281
282 numpy_type = getattr(numpy, py_type[7:-2])
283
284
285 value = zeros(value.shape, numpy_type)
286
287
288 if isinstance(value[0], ndarray):
289 for i in range(len(value)):
290 for j in range(len(value[i])):
291 value[i, j] = packBytesAsPyFloat(ieee_value[i][j])
292
293
294 else:
295 for i in range(len(value)):
296 value[i] = packBytesAsPyFloat(ieee_value[i])
297
298
299 setattr(base_object, name, value)
300