55 python -m odml.tools.xmlparser file.odml
66"""
77import csv
8+ import sys
89from lxml import etree as ET
910from lxml .builder import E
1011# this is needed for py2exe to include lxml completely
1112from lxml import _elementpath as _dummy
12- import sys
1313
1414try :
1515 from StringIO import StringIO
@@ -118,10 +118,9 @@ def write_file(self, filename):
118118 else :
119119 data = str (self )
120120
121- f = open (filename , "w" )
122- f .write (self .header )
123- f .write (data )
124- f .close ()
121+ with open (filename , "w" ) as file :
122+ file .write (self .header )
123+ file .write (data )
125124
126125
127126def load (filename ):
@@ -223,18 +222,20 @@ def parse_element(self, node):
223222 return None # won't be able to parse this one
224223 return getattr (self , "parse_" + node .tag )(node , self .tags [node .tag ])
225224
226- def parse_tag (self , root , fmt , insert_children = True , create = None ):
225+ def parse_tag (self , root , fmt , insert_children = True ):
227226 """
228227 Parse an odml node based on the format description *fmt*
229- and a function *create* to instantiate a corresponding object
228+ and instantiate the corresponding object.
229+ :param root: lxml.etree node containing an odML object or object tree.
230+ :param fmt: odML class corresponding to the content of the root node.
231+ :param insert_children: Bool value. When True, child elements of the root node
232+ will be parsed to their odML equivalents and appended to
233+ the odML document. When False, child elements of the
234+ root node will be ignored.
230235 """
231236 arguments = {}
232237 extra_args = {}
233238 children = []
234- text = []
235-
236- if root .text :
237- text .append (root .text .strip ())
238239
239240 for k , v in root .attrib .iteritems ():
240241 k = k .lower ()
@@ -258,8 +259,6 @@ def parse_tag(self, root, fmt, insert_children=True, create=None):
258259 else :
259260 tag = fmt .map (node .tag )
260261 if tag in arguments :
261- # TODO make this an error, however first figure out a
262- # way to let <odML version=><version/> pass
263262 self .warn ("Element <%s> is given multiple times in "
264263 "<%s> tag" % (node .tag , root .tag ), node )
265264
@@ -273,63 +272,32 @@ def parse_tag(self, root, fmt, insert_children=True, create=None):
273272 else :
274273 self .error ("Invalid element <%s> in odML document section <%s>"
275274 % (node .tag , root .tag ), node )
276- if node .tail :
277- text .append (node .tail .strip ())
278275
279276 if sys .version_info > (3 ,):
280- self .check_mandatory_arguments (dict (list (arguments .items ()) +
281- list (extra_args .items ())),
282- fmt , root .tag , root )
277+ check_args = dict (list (arguments .items ()) + list (extra_args .items ()))
283278 else :
284- self .check_mandatory_arguments (dict (arguments .items () +
285- extra_args .items ()),
286- fmt , root .tag , root )
287- if create is None :
288- obj = fmt .create ()
289- else :
290- obj = create (args = arguments , text = '' .join (text ), children = children )
279+ check_args = dict (arguments .items () + extra_args .items ())
291280
292- for k , v in arguments .items ():
293- if hasattr (obj , k ) and (getattr (obj , k ) is None or k == 'id' ):
294- try :
295- if k == 'id' and v is not None :
296- obj ._id = v
297- else :
298- setattr (obj , k , v )
299- except Exception as e :
300- self .warn ("cannot set '%s' property on <%s>: %s" %
301- (k , root .tag , repr (e )), root )
302- if not self .ignore_errors :
303- raise e
281+ self .check_mandatory_arguments (check_args , fmt , root .tag , root )
282+
283+ # Instantiate the current odML object with the parsed attributes.
284+ obj = fmt .create (** arguments )
304285
305286 if insert_children :
306287 for child in children :
307288 obj .append (child )
289+
308290 return obj
309291
310292 def parse_odML (self , root , fmt ):
311293 doc = self .parse_tag (root , fmt )
312294 return doc
313295
314296 def parse_section (self , root , fmt ):
315- name = root .get ("name" ) # property name= overrides
316- if name is None : # the element
317- name_node = root .find ("name" )
318- if name_node is not None :
319- name = name_node .text
320- root .remove (name_node )
321- # delete the name_node so its value won't
322- # be used to overwrite the already set name-attribute
323-
324- if name is None :
325- self .error ("Missing name element in <section>" , root )
326-
327- return self .parse_tag (root , fmt ,
328- create = lambda ** kargs : fmt .create (name ))
297+ return self .parse_tag (root , fmt )
329298
330299 def parse_property (self , root , fmt ):
331- create = lambda children , args , ** kargs : fmt .create (** args )
332- return self .parse_tag (root , fmt , insert_children = False , create = create )
300+ return self .parse_tag (root , fmt , insert_children = False )
333301
334302
335303if __name__ == '__main__' :
0 commit comments