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