1 from xml.etree.ElementTree import parse as parse_xml
2 from .base import INT, UINT, FLOAT, STRING, UNICODE, DATE, BINARY, CONTAINER, Element, Document
17 def parse_specdata(source, doc_name, doc_type, doc_version):
20 Reads a schema specification from a file (e.g., specdata.xml) or file-like object, and returns a tuple containing:
22 * a mapping of class names to Element subclasses
25 :arg source: the file or file-like object
26 :type source: str or file-like object
27 :arg schema_name: the name of the schema
28 :type schema_name: str
33 tree = parse_xml(source)
37 def child_elements(parent_level, element_list, upper_recursive=None):
40 raw_element = element_list[0]
41 raw_attrs = raw_element.attrib
43 element_level = int(raw_attrs['level'])
46 if element_level == -1:
48 elif parent_level is not None and not element_level > parent_level:
50 element_list = element_list[1:]
52 element_name = '%sElement' % raw_attrs.get('cppname', raw_attrs.get('name')).translate(None, '-')
55 'id': int(raw_attrs['id'], 0),
56 'name': raw_attrs['name'],
57 'type': SPECDATA_TYPES[raw_attrs['type']],
58 'mandatory': True if raw_attrs.get('mandatory', False) == '1' else False,
59 'multiple': True if raw_attrs.get('multiple', False) == '1' else False
62 element_attrs['default'] = {
63 INT: lambda default: int(default),
64 UINT: lambda default: int(default),
65 FLOAT: lambda default: float(default),
66 STRING: lambda default: str(default),
67 UNICODE: lambda default: unicode(default)
68 }.get(element_attrs['type'], lambda default: default)(raw_attrs['default'])
69 except (KeyError, ValueError):
70 element_attrs['default'] = None
72 element = type(element_name, (Element,), element_attrs)
73 elements[element_name] = element
77 recursive.extend(upper_recursive)
78 if raw_attrs.get('recursive', False) == '1':
79 recursive.append(element)
81 element_children, element_list = child_elements(element_level if not is_global else 0, element_list, recursive)
82 element_children += tuple(recursive)
83 element.children = element_children
86 globals.append(element)
88 children.append(element)
89 return tuple(children), element_list
91 children = child_elements(None, tree.getroot().getchildren())[0]
96 'version': doc_version,
98 'globals': tuple(globals)
100 document = type(doc_name, (Document,), document_attrs)
102 return elements, document