1010Thin layer around xml.etree.ElementTree, to abstract nibabel xml support.
1111"""
1212from xml .etree .ElementTree import Element , SubElement , tostring
13+ from xml .parsers .expat import ParserCreate , ExpatError
1314
1415from .filebasedimages import FileBasedHeader , FileBasedImage
1516
@@ -31,7 +32,61 @@ class XmlBasedHeader(FileBasedHeader, XmlSerializable):
3132 pass
3233
3334
35+ class XmlImageParser (object ):
36+ """ Parse XML image"""
37+
38+ HANDLER_NAMES = ['StartElementHandler' ,
39+ 'EndElementHandler' ,
40+ 'CharacterDataHandler' ]
41+
42+ def __init__ (self , encoding = None ):
43+ self .encoding = encoding
44+ self .img = None
45+
46+ def parse (self , string = None , fname = None , fptr = None ):
47+ """
48+ Parameters
49+ ----------
50+ string : str
51+ string containing xml document
52+
53+ fname : str
54+ file name of an xml document.
55+
56+ fptr : file pointer
57+ open file pointer to an xml document
58+
59+ Returns
60+ -------
61+ img : XmlBasedImage
62+ """
63+ if int (fname is not None ) + int (fptr is not None ) + int (fname is not None ) != 1 :
64+ raise ValueError ('Exactly one of fptr, fname, string must be specified.' )
65+
66+ if string is not None :
67+ fptr = StringIO (string )
68+ elif fname is not None :
69+ fptr = open (fname , 'r' )
70+
71+ parser = ParserCreate () # from xml package
72+ for name in self .HANDLER_NAMES :
73+ setattr (parser , name , getattr (self , name ))
74+ parser .ParseFile (fptr )
75+
76+ return self .img
77+
78+ def StartElementHandler (self , name , attrs ):
79+ raise NotImplementedError
80+
81+ def EndElementHandler (self , name ):
82+ raise NotImplementedError
83+
84+ def CharacterDataHandler (self , data ):
85+ raise NotImplementedError
86+
87+
3488class XmlBasedImage (FileBasedImage , XmlSerializable ):
89+ parser = XmlImageParser
3590
3691 def to_file_map (self , file_map = None ):
3792 """ Save the current image to the specified file_map
@@ -48,3 +103,18 @@ def to_file_map(self, file_map=None):
48103 file_map = self .file_map
49104 f = file_map ['image' ].get_prepare_fileobj ('wb' )
50105 f .write (self .to_xml ())
106+
107+ @classmethod
108+ def from_file_map (klass , file_map ):
109+ """ Load a Gifti image from a file_map
110+
111+ Parameters
112+ file_map : string
113+
114+ Returns
115+ -------
116+ img : GiftiImage
117+ Returns a GiftiImage
118+ """
119+ return parser .parse (
120+ fptr = file_map ['image' ].get_prepare_fileobj ('rb' ))
0 commit comments