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