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, int16, int32, float32, float64, 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 is 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 value:
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, none_elements=True, raise_error=False):
182
183 ieee_obj = []
184 for i in range(len(value)):
185
186 if value[i] is None:
187 ieee_obj.append(None)
188 continue
189
190
191 ieee_obj.append([])
192 for j in range(len(value[i])):
193 ieee_obj[-1].append(floatAsByteArray(value[i][j]))
194
195
196 val_elem = doc.createElement('ieee_754_byte_array')
197 elem.appendChild(val_elem)
198
199
200 val_elem.appendChild(doc.createTextNode(repr(ieee_obj)))
201
202
203 -def xml_to_object(elem, base_object=None, set_fn=None, file_version=1, blacklist=[]):
204 """Convert the XML elements into python objects, and place these into the base object.
205
206 @param elem: The element to extract all python objects from.
207 @type elem: xml.dom.minidom.Element instance
208 @keyword base_object: The python class instance to place the objects into.
209 @type base_object: instance
210 @keyword set_fn: A function used to replace setattr for placing the object into the base
211 object.
212 @type set_fn: function
213 @keyword file_version: The relax XML version of the XML file.
214 @type file_version: int
215 @keyword blacklist: A list of object names to exclude.
216 @type blacklist: list of str
217 """
218
219
220 for node in elem.childNodes:
221
222 if node.localName == None:
223 continue
224
225
226 name = str(node.localName)
227
228
229 if name in blacklist:
230 continue
231
232
233 if file_version == 1:
234
235 ieee_array = node.getAttribute('ieee_754_byte_array')
236 if ieee_array:
237 value = packBytesAsPyFloat(eval(ieee_array))
238
239
240 else:
241 value = node_value_to_python(node.childNodes[0])
242
243
244 elif file_version == 2:
245
246 py_type = node.getAttribute('type')
247 if not search('dtype', py_type):
248 py_type = eval(py_type)
249
250
251 ieee_value = None
252 for sub_node in node.childNodes:
253
254 if sub_node.localName == 'value':
255 value = node_value_to_python(sub_node.childNodes[0])
256
257
258 if sub_node.localName == 'ieee_754_byte_array':
259 ieee_value = node_value_to_python(sub_node.childNodes[0])
260
261
262 if ieee_value:
263
264 if py_type == float:
265 value = packBytesAsPyFloat(ieee_value)
266
267
268 elif py_type == dict:
269 for key in ieee_value:
270 value[key] = packBytesAsPyFloat(ieee_value[key])
271
272
273 elif py_type == list:
274
275 for i in range(len(value)):
276
277 if isinstance(value[i], list) or isinstance(value[i], ndarray):
278 for j in range(len(value[i])):
279 value[i][j] = packBytesAsPyFloat(ieee_value[i][j])
280
281
282 elif ieee_value[i] == None:
283 value[i] = None
284
285
286 else:
287 value[i] = packBytesAsPyFloat(ieee_value[i])
288
289
290 elif search('dtype', py_type):
291
292 numpy_type = getattr(numpy, py_type[7:-2])
293
294
295 value = zeros(value.shape, numpy_type)
296
297
298 if isinstance(value[0], ndarray):
299 for i in range(len(value)):
300 for j in range(len(value[i])):
301 value[i, j] = packBytesAsPyFloat(ieee_value[i][j])
302
303
304 else:
305 for i in range(len(value)):
306 value[i] = packBytesAsPyFloat(ieee_value[i])
307
308
309 setattr(base_object, name, value)
310