2323import base64
2424
2525
26- class GiftiMetaData (object ):
26+ class XmlSerializable (object ):
27+ """ Basic interface for serializing an object to xml"""
28+ def _to_xml_element (self ):
29+ """ Output should be a xml.etree.ElementTree.Element"""
30+ raise NotImplementedError ()
31+
32+ def to_xml (self , enc = 'utf-8' ):
33+ """ Output should be an xml string with the given encoding.
34+ (default: utf-8)"""
35+ return xml .tostring (self ._to_xml_element (), enc )
36+
37+
38+ class GiftiMetaData (XmlSerializable ):
2739 """ A list of GiftiNVPairs in stored in
2840 the list self.data """
2941 def __init__ (self , nvpair = None ):
@@ -51,15 +63,15 @@ def metadata(self):
5163 self .data_as_dict [ele .name ] = ele .value
5264 return self .data_as_dict
5365
54- def to_xml (self ):
66+ def _to_xml_element (self ):
5567 metadata = xml .Element ('MetaData' )
5668 for ele in self .data :
5769 md = xml .SubElement (metadata , 'MD' )
5870 name = xml .SubElement (md , 'Name' )
5971 value = xml .SubElement (md , 'Value' )
6072 name .text = ele .name
6173 value .text = ele .value
62- return xml . tostring ( metadata , 'utf-8' )
74+ return metadata
6375
6476 def print_summary (self ):
6577 print (self .metadata )
@@ -75,7 +87,7 @@ def __init__(self, name='', value=''):
7587 self .value = value
7688
7789
78- class GiftiLabelTable (object ):
90+ class GiftiLabelTable (XmlSerializable ):
7991
8092 def __init__ (self ):
8193 self .labels = []
@@ -86,7 +98,7 @@ def get_labels_as_dict(self):
8698 self .labels_as_dict [ele .key ] = ele .label
8799 return self .labels_as_dict
88100
89- def to_xml (self ):
101+ def _to_xml_element (self ):
90102 labeltable = xml .Element ('LabelTable' )
91103 for ele in self .labels :
92104 label = xml .SubElement (labeltable , 'Label' )
@@ -95,13 +107,13 @@ def to_xml(self):
95107 for attr in ['Red' , 'Green' , 'Blue' , 'Alpha' ]:
96108 if getattr (ele , attr .lower (), None ) is not None :
97109 label .attrib [attr ] = str (getattr (ele , attr .lower ()))
98- return xml . tostring ( labeltable , 'utf-8' )
110+ return labeltable
99111
100112 def print_summary (self ):
101113 print (self .get_labels_as_dict ())
102114
103115
104- class GiftiLabel (object ):
116+ class GiftiLabel (XmlSerializable ):
105117 key = int
106118 label = str
107119 # rgba
@@ -154,7 +166,7 @@ def _arr2txt(arr, elem_fmt):
154166 return '\n ' .join (fmt % tuple (row ) for row in arr )
155167
156168
157- class GiftiCoordSystem (object ):
169+ class GiftiCoordSystem (XmlSerializable ):
158170 dataspace = int
159171 xformspace = int
160172 xform = np .ndarray # 4x4 numpy array
@@ -168,7 +180,7 @@ def __init__(self, dataspace=0, xformspace=0, xform=None):
168180 else :
169181 self .xform = xform
170182
171- def to_xml (self ):
183+ def _to_xml_element (self ):
172184 coord_xform = xml .Element ('CoordinateSystemTransformMatrix' )
173185 if self .xform is not None :
174186 dataspace = xml .SubElement (coord_xform , 'DataSpace' )
@@ -177,15 +189,15 @@ def to_xml(self):
177189 xformed_space .text = xform_codes .niistring [self .xformspace ]
178190 matrix_data = xml .SubElement (coord_xform , 'MatrixData' )
179191 matrix_data .text = _arr2txt (self .xform , '%10.6f' )
180- return xml . tostring ( coord_xform , 'utf-8' )
192+ return coord_xform
181193
182194 def print_summary (self ):
183195 print ('Dataspace: ' , xform_codes .niistring [self .dataspace ])
184196 print ('XFormSpace: ' , xform_codes .niistring [self .xformspace ])
185197 print ('Affine Transformation Matrix: \n ' , self .xform )
186198
187199
188- def data_tag (dataarray , encoding , datatype , ordering ):
200+ def _data_tag_element (dataarray , encoding , datatype , ordering ):
189201 """ Creates the data tag depending on the required encoding,
190202 returns as bytes"""
191203 import zlib
@@ -205,10 +217,15 @@ def data_tag(dataarray, encoding, datatype, ordering):
205217
206218 data = xml .Element ('Data' )
207219 data .text = da
220+ return data
221+
222+
223+ def data_tag (dataarray , encoding , datatype , ordering ):
224+ data = _data_tag_element (dataarray , encoding , datatype , ordering )
208225 return xml .tostring (data , 'utf-8' )
209226
210227
211- class GiftiDataArray (object ):
228+ class GiftiDataArray (XmlSerializable ):
212229
213230 # These are for documentation only; we don't use these class variables
214231 intent = int
@@ -289,7 +306,7 @@ def from_array(klass,
289306 cda .meta = GiftiMetaData .from_dict (meta )
290307 return cda
291308
292- def to_xml (self ):
309+ def _to_xml_element (self ):
293310 # fix endianness to machine endianness
294311 self .endian = gifti_endian_codes .code [sys .byteorder ]
295312
@@ -306,18 +323,18 @@ def to_xml(self):
306323 data_array .attrib ['Dim%d' % di ] = str (dn )
307324
308325 if self .meta is not None :
309- data_array .append (xml . fromstring ( self .meta .to_xml () ))
326+ data_array .append (self .meta ._to_xml_element ( ))
310327 if self .coordsys is not None :
311- data_array .append (xml . fromstring ( self .coordsys .to_xml () ))
328+ data_array .append (self .coordsys ._to_xml_element ( ))
312329 # write data array depending on the encoding
313330 dt_kind = data_type_codes .dtype [self .datatype ].kind
314- data_array .append (xml . fromstring (
315- data_tag (self .data ,
316- gifti_encoding_codes .specs [self .encoding ],
317- KIND2FMT [dt_kind ],
318- self .ind_ord ) ))
331+ data_array .append (
332+ _data_tag_element (self .data ,
333+ gifti_encoding_codes .specs [self .encoding ],
334+ KIND2FMT [dt_kind ],
335+ self .ind_ord ))
319336
320- return xml . tostring ( data_array , 'utf-8' )
337+ return data_array
321338
322339 def print_summary (self ):
323340 print ('Intent: ' , intent_codes .niistring [self .intent ])
@@ -345,7 +362,8 @@ def metadata(self):
345362 return self .meta .metadata
346363
347364
348- class GiftiImage (object ):
365+ class GiftiImage (XmlSerializable ):
366+
349367 def __init__ (self , meta = None , labeltable = None , darrays = None ,
350368 version = "1.0" ):
351369 if darrays is None :
@@ -472,18 +490,20 @@ def print_summary(self):
472490 print ('----end----' )
473491
474492
475- def to_xml (self ):
476- """ Return XML corresponding to image content """
493+ def _to_xml_element (self ):
477494 GIFTI = xml .Element ('GIFTI' , attrib = {
478495 'Version' : self .version ,
479496 'NumberOfDataArrays' : str (self .numDA )})
480497 if self .meta is not None :
481- GIFTI .append (xml . fromstring ( self .meta .to_xml () ))
498+ GIFTI .append (self .meta ._to_xml_element ( ))
482499 if self .labeltable is not None :
483- GIFTI .append (xml . fromstring ( self .labeltable .to_xml () ))
500+ GIFTI .append (self .labeltable ._to_xml_element ( ))
484501 for dar in self .darrays :
485- GIFTI .append (xml .fromstring (dar .to_xml ()))
502+ GIFTI .append (dar ._to_xml_element ())
503+ return GIFTI
486504
505+ def to_xml (self , enc = 'utf-8' ):
506+ """ Return XML corresponding to image content """
487507 return b"""<?xml version="1.0" encoding="UTF-8"?>
488508<!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/115/gifti.dtd">
489- """ + xml . tostring ( GIFTI , 'utf-8' )
509+ """ + XmlSerializable . to_xml ( self , enc )
0 commit comments