5
5
python -m odml.tools.xmlparser file.odml
6
6
"""
7
7
import csv
8
+ import sys
8
9
from lxml import etree as ET
9
10
from lxml .builder import E
10
11
# this is needed for py2exe to include lxml completely
11
12
from lxml import _elementpath as _dummy
12
- import sys
13
13
14
14
try :
15
15
from StringIO import StringIO
@@ -118,10 +118,9 @@ def write_file(self, filename):
118
118
else :
119
119
data = str (self )
120
120
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 )
125
124
126
125
127
126
def load (filename ):
@@ -223,18 +222,20 @@ def parse_element(self, node):
223
222
return None # won't be able to parse this one
224
223
return getattr (self , "parse_" + node .tag )(node , self .tags [node .tag ])
225
224
226
- def parse_tag (self , root , fmt , insert_children = True , create = None ):
225
+ def parse_tag (self , root , fmt , insert_children = True ):
227
226
"""
228
227
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.
230
235
"""
231
236
arguments = {}
232
237
extra_args = {}
233
238
children = []
234
- text = []
235
-
236
- if root .text :
237
- text .append (root .text .strip ())
238
239
239
240
for k , v in root .attrib .iteritems ():
240
241
k = k .lower ()
@@ -258,8 +259,6 @@ def parse_tag(self, root, fmt, insert_children=True, create=None):
258
259
else :
259
260
tag = fmt .map (node .tag )
260
261
if tag in arguments :
261
- # TODO make this an error, however first figure out a
262
- # way to let <odML version=><version/> pass
263
262
self .warn ("Element <%s> is given multiple times in "
264
263
"<%s> tag" % (node .tag , root .tag ), node )
265
264
@@ -273,63 +272,32 @@ def parse_tag(self, root, fmt, insert_children=True, create=None):
273
272
else :
274
273
self .error ("Invalid element <%s> in odML document section <%s>"
275
274
% (node .tag , root .tag ), node )
276
- if node .tail :
277
- text .append (node .tail .strip ())
278
275
279
276
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 ()))
283
278
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 ())
291
280
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 )
304
285
305
286
if insert_children :
306
287
for child in children :
307
288
obj .append (child )
289
+
308
290
return obj
309
291
310
292
def parse_odML (self , root , fmt ):
311
293
doc = self .parse_tag (root , fmt )
312
294
return doc
313
295
314
296
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 )
329
298
330
299
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 )
333
301
334
302
335
303
if __name__ == '__main__' :
0 commit comments