99from __future__ import division , print_function , absolute_import
1010
1111import sys
12+ import xml .etree .ElementTree as xml
1213
1314import numpy as np
1415
@@ -51,17 +52,14 @@ def metadata(self):
5152 return self .data_as_dict
5253
5354 def to_xml (self ):
54- if len (self .data ) == 0 :
55- return b"<MetaData/>\n "
56- res = "<MetaData>\n "
55+ metadata = xml .Element ('MetaData' )
5756 for ele in self .data :
58- nvpair = """<MD>
59- \t <Name><![CDATA[%s]]></Name>
60- \t <Value><![CDATA[%s]]></Value>
61- </MD>\n """ % (ele .name , ele .value )
62- res = res + nvpair
63- res = res + "</MetaData>\n "
64- return res .encode ('utf-8' )
57+ md = xml .SubElement (metadata , 'MD' )
58+ name = xml .SubElement (md , 'Name' )
59+ value = xml .SubElement (md , 'Value' )
60+ name .text = ele .name
61+ value .text = ele .value
62+ return xml .tostring (metadata , 'utf-8' )
6563
6664 def print_summary (self ):
6765 print (self .metadata )
@@ -89,24 +87,15 @@ def get_labels_as_dict(self):
8987 return self .labels_as_dict
9088
9189 def to_xml (self ):
92- if len (self .labels ) == 0 :
93- return b"<LabelTable/>\n "
94- res = "<LabelTable>\n "
90+ labeltable = xml .Element ('LabelTable' )
9591 for ele in self .labels :
96- col = ''
97- if not ele .red is None :
98- col += ' Red="%s"' % str (ele .red )
99- if not ele .green is None :
100- col += ' Green="%s"' % str (ele .green )
101- if not ele .blue is None :
102- col += ' Blue="%s"' % str (ele .blue )
103- if not ele .alpha is None :
104- col += ' Alpha="%s"' % str (ele .alpha )
105- lab = """\t <Label Key="%s"%s><![CDATA[%s]]></Label>\n """ % \
106- (str (ele .key ), col , ele .label )
107- res = res + lab
108- res = res + "</LabelTable>\n "
109- return res .encode ('utf-8' )
92+ label = xml .SubElement (labeltable , 'Label' )
93+ label .attrib ['Key' ] = str (ele .key )
94+ label .text = ele .label
95+ for attr in ['Red' , 'Green' , 'Blue' , 'Alpha' ]:
96+ if getattr (ele , attr .lower (), None ) is not None :
97+ label .attrib [attr ] = str (getattr (ele , attr .lower ()))
98+ return xml .tostring (labeltable , 'utf-8' )
11099
111100 def print_summary (self ):
112101 print (self .get_labels_as_dict ())
@@ -180,18 +169,15 @@ def __init__(self, dataspace=0, xformspace=0, xform=None):
180169 self .xform = xform
181170
182171 def to_xml (self ):
183- if self .xform is None :
184- return b"<CoordinateSystemTransformMatrix/>\n "
185- res = ("""<CoordinateSystemTransformMatrix>
186- \t <DataSpace><![CDATA[%s]]></DataSpace>
187- \t <TransformedSpace><![CDATA[%s]]></TransformedSpace>\n """
188- % (xform_codes .niistring [self .dataspace ],
189- xform_codes .niistring [self .xformspace ]))
190- res = res + "<MatrixData>\n "
191- res += _arr2txt (self .xform , '%10.6f' )
192- res = res + "</MatrixData>\n "
193- res = res + "</CoordinateSystemTransformMatrix>\n "
194- return res .encode ('utf-8' )
172+ coord_xform = xml .Element ('CoordinateSystemTransformMatrix' )
173+ if self .xform is not None :
174+ dataspace = xml .SubElement (coord_xform , 'DataSpace' )
175+ dataspace .text = xform_codes .niistring [self .dataspace ]
176+ xformed_space = xml .SubElement (coord_xform , 'TransformedSpace' )
177+ xformed_space .text = xform_codes .niistring [self .xformspace ]
178+ matrix_data = xml .SubElement (coord_xform , 'MatrixData' )
179+ matrix_data .text = _arr2txt (self .xform , '%10.6f' )
180+ return xml .tostring (coord_xform , 'utf-8' )
195181
196182 def print_summary (self ):
197183 print ('Dataspace: ' , xform_codes .niistring [self .dataspace ])
@@ -216,7 +202,10 @@ def data_tag(dataarray, encoding, datatype, ordering):
216202 raise NotImplementedError ("In what format are the external files?" )
217203 else :
218204 da = ''
219- return ("<Data>" + da + "</Data>\n " ).encode ('utf-8' )
205+
206+ data = xml .Element ('Data' )
207+ data .text = da
208+ return xml .tostring (data , 'utf-8' )
220209
221210
222211class GiftiDataArray (object ):
@@ -303,48 +292,32 @@ def from_array(klass,
303292 def to_xml (self ):
304293 # fix endianness to machine endianness
305294 self .endian = gifti_endian_codes .code [sys .byteorder ]
306- result = ""
307- result += self .to_xml_open ().decode ('utf-8' )
308- # write metadata
309- if not self .meta is None :
310- result += self .meta .to_xml ().decode ('utf-8' )
311- # write coord sys
312- if not self .coordsys is None :
313- result += self .coordsys .to_xml ().decode ('utf-8' )
295+
296+ data_array = xml .Element ('DataArray' , attrib = {
297+ 'Intent' : intent_codes .niistring [self .intent ],
298+ 'DataType' : data_type_codes .niistring [self .datatype ],
299+ 'ArrayIndexingOrder' : array_index_order_codes .label [self .ind_ord ],
300+ 'Dimensionality' : str (self .num_dim ),
301+ 'Encoding' : gifti_encoding_codes .specs [self .encoding ],
302+ 'Endian' : gifti_endian_codes .specs [self .endian ],
303+ 'ExternalFileName' : self .ext_fname ,
304+ 'ExternalFileOffset' : self .ext_offset })
305+ for di , dn in enumerate (self .dims ):
306+ data_array .attrib ['Dim%d' % di ] = str (dn )
307+
308+ if self .meta is not None :
309+ data_array .append (xml .fromstring (self .meta .to_xml ()))
310+ if self .coordsys is not None :
311+ data_array .append (xml .fromstring (self .coordsys .to_xml ()))
314312 # write data array depending on the encoding
315313 dt_kind = data_type_codes .dtype [self .datatype ].kind
316- result += data_tag (self .data ,
317- gifti_encoding_codes .specs [self .encoding ],
318- KIND2FMT [dt_kind ],
319- self .ind_ord ).decode ('utf-8' )
320- result = result + self .to_xml_close ().decode ('utf-8' )
321- return result .encode ('utf-8' )
322-
323- def to_xml_open (self ):
324- out = """<DataArray Intent="%s"
325- \t DataType="%s"
326- \t ArrayIndexingOrder="%s"
327- \t Dimensionality="%s"
328- %s\t Encoding="%s"
329- \t Endian="%s"
330- \t ExternalFileName="%s"
331- \t ExternalFileOffset="%s">\n """
332- di = ""
333- for i , n in enumerate (self .dims ):
334- di = di + '\t Dim%s=\" %s\" \n ' % (str (i ), str (n ))
335- return (out % (intent_codes .niistring [self .intent ],
336- data_type_codes .niistring [self .datatype ],
337- array_index_order_codes .label [self .ind_ord ],
338- str (self .num_dim ),
339- str (di ),
340- gifti_encoding_codes .specs [self .encoding ],
341- gifti_endian_codes .specs [self .endian ],
342- self .ext_fname ,
343- self .ext_offset ,
344- )).encode ('utf-8' )
345-
346- def to_xml_close (self ):
347- return b"</DataArray>\n "
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 )))
319+
320+ return xml .tostring (data_array , 'utf-8' )
348321
349322 def print_summary (self ):
350323 print ('Intent: ' , intent_codes .niistring [self .intent ])
@@ -498,17 +471,19 @@ def print_summary(self):
498471 print (da .print_summary ())
499472 print ('----end----' )
500473
474+
501475 def to_xml (self ):
502476 """ Return XML corresponding to image content """
503- res = """<?xml version="1.0" encoding="UTF-8"?>
504- <!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/115/gifti.dtd">
505- <GIFTI Version="%s" NumberOfDataArrays="%s">\n """ % (self .version ,
506- str (self .numDA ))
507- if not self .meta is None :
508- res += self .meta .to_xml ().decode ('utf-8' )
509- if not self .labeltable is None :
510- res += self .labeltable .to_xml ().decode ('utf-8' )
477+ GIFTI = xml .Element ('GIFTI' , attrib = {
478+ 'Version' : self .version ,
479+ 'NumberOfDataArrays' : str (self .numDA )})
480+ if self .meta is not None :
481+ GIFTI .append (xml .fromstring (self .meta .to_xml ()))
482+ if self .labeltable is not None :
483+ GIFTI .append (xml .fromstring (self .labeltable .to_xml ()))
511484 for dar in self .darrays :
512- res += dar .to_xml ().decode ('utf-8' )
513- res += "</GIFTI>"
514- return res .encode ('utf-8' )
485+ GIFTI .append (xml .fromstring (dar .to_xml ()))
486+
487+ return b"""<?xml version="1.0" encoding="UTF-8"?>
488+ <!DOCTYPE GIFTI SYSTEM "http://www.nitrc.org/frs/download.php/115/gifti.dtd">
489+ """ + xml .tostring (GIFTI , 'utf-8' )
0 commit comments