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 fns for creation and parsing of XML representations of python objects."""
24
25
26 import numpy
27 from numpy import set_printoptions, array, float32, float64, inf, nan, ndarray, zeros
28 try:
29 from numpy import float16
30 except ImportError:
31 float16 = float32
32 try:
33 from numpy import float128
34 except ImportError:
35 float128 = float64
36 from re import search
37
38
39 set_printoptions(precision=15, threshold=nan)
40
41
42 import arg_check
43 from float import floatAsByteArray, packBytesAsPyFloat
44 from relax_errors import RelaxError
45
46
47 -def fill_object_contents(doc, elem, object=None, blacklist=[]):
48 """Place all simple python objects into the XML element namespace.
49
50 @param doc: The XML document object.
51 @type doc: xml.dom.minidom.Document instance
52 @param elem: The element to add all python objects to.
53 @type elem: XML element object
54 @keyword object: The python class instance containing the objects to add.
55 @type object: instance
56 @keyword blacklist: A list of object names to exclude.
57 @type blacklist: list of str
58 """
59
60
61 for name in dir(object):
62
63 if name in blacklist:
64 continue
65
66
67 if search("^_", name):
68 continue
69
70
71 if hasattr(object, '_mod_attr') and name not in object._mod_attr:
72 continue
73
74
75 sub_elem = doc.createElement(name)
76 elem.appendChild(sub_elem)
77
78
79 subobj = getattr(object, name)
80
81
82 object_to_xml(doc, sub_elem, value=subobj)
83
84
86 """Convert the node value to a python expression.
87
88 @param elem: The XML element.
89 @type elem: xml.dom.minidom.Element instance
90 """
91
92
93 val = elem.nodeValue.strip()
94
95
96 return eval(val)
97
98
100 """Convert the given value into an XML form.
101
102 @param doc: The XML document object.
103 @type doc: xml.dom.minidom.Document instance
104 @param elem: The element to add the Python objects to.
105 @type elem: XML element object
106 @keyword value: The Python object to convert.
107 @type value: anything
108 """
109
110
111 val_elem = doc.createElement('value')
112 elem.appendChild(val_elem)
113 val_elem.appendChild(doc.createTextNode(repr(value)))
114
115
116 if value == None:
117 py_type = 'None'
118 elif isinstance(value, bool):
119 py_type = 'bool'
120 elif isinstance(value, str):
121 py_type = 'str'
122 elif isinstance(value, float):
123 py_type = 'float'
124 elif isinstance(value, int):
125 py_type = 'int'
126 elif isinstance(value, list):
127 py_type = 'list'
128 elif isinstance(value, dict):
129 py_type = 'dict'
130 elif isinstance(value, ndarray):
131 py_type = repr(value.dtype)
132 else:
133 raise RelaxError("Unknown type for the value '%s'." % value)
134
135
136 elem.setAttribute('type', py_type)
137
138
139 if arg_check.check_float(value):
140 val_elem = doc.createElement('ieee_754_byte_array')
141 elem.appendChild(val_elem)
142 val_elem.appendChild(doc.createTextNode(repr(floatAsByteArray(value))))
143
144
145 elif (isinstance(value, list) or isinstance(value, ndarray)) and len(value) and arg_check.check_float(value[0]):
146
147 ieee_obj = []
148 conv = False
149 for i in range(len(value)):
150
151 if arg_check.check_float(value[i]):
152 ieee_obj.append(floatAsByteArray(value[i]))
153 conv = True
154
155
156 else:
157 ieee_obj.append(value)
158
159
160 if conv:
161
162 val_elem = doc.createElement('ieee_754_byte_array')
163 elem.appendChild(val_elem)
164
165
166 val_elem.appendChild(doc.createTextNode(repr(ieee_obj)))
167
168
169 elif py_type == 'dict':
170
171 ieee_obj = {}
172 conv = False
173 for key in list(value.keys()):
174 if arg_check.check_float(value[key]):
175 ieee_obj[key] = floatAsByteArray(value[key])
176 conv = True
177
178
179 if conv:
180
181 val_elem = doc.createElement('ieee_754_byte_array')
182 elem.appendChild(val_elem)
183
184
185 val_elem.appendChild(doc.createTextNode(repr(ieee_obj)))
186
187
188 elif arg_check.is_float_matrix(value, raise_error=False):
189
190 ieee_obj = []
191 for i in range(len(value)):
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 else:
284 value[i] = packBytesAsPyFloat(ieee_value[i])
285
286
287 elif search('dtype', py_type):
288
289 numpy_type = getattr(numpy, py_type[7:-2])
290
291
292 value = zeros(value.shape, numpy_type)
293
294
295 if isinstance(value[0], ndarray):
296 for i in range(len(value)):
297 for j in range(len(value[i])):
298 value[i, j] = packBytesAsPyFloat(ieee_value[i][j])
299
300
301 else:
302 for i in range(len(value)):
303 value[i] = packBytesAsPyFloat(ieee_value[i])
304
305
306 setattr(base_object, name, value)
307