def __init__(self, xsd_file): self._xsd = None self._xml_schema = None self.namespaces = self.XML_SCHEMA_NAMESPACES.copy() "Namespaces used by XSD file" self.target_namespace = None "Target namespace URI" self.target_prefix = '' "Namespace prefix for declarations" # Temporary mods for preserve types declaration order for Fortran generation from collections import OrderedDict self.types = OrderedDict() # {} "Map XSD global types to XSDType instance" self.attributes = {} "Map XSD global attributes to XSDType instance" self.attribute_groups = {} "Group XSD attributes definitions" self.elements = {} "Map XSD global elements to XSDType instance" self.groups = {} "Group XSD elements definitions" try: self._xsd = ElementTree.parse(xsd_file) except ElementTree.ParseError as e: raise FileFormatError('XML', xsd_file, e.msg) else: self._xsd_file = xsd_file try: self._xml_schema = ElementTree.XMLSchema(self._xsd) except AttributeError: logger.info("XSD validation is not available!") except ElementTree.XMLSchemaError as e: logger.error("XSD schema error: %s " % repr(e)) raise # Set the namespaces information schema_elem = self.getroot() self.target_namespace = schema_elem.attrib['targetNamespace'] logger.debug("Target namespace: %s" % self.target_namespace) if hasattr(schema_elem, 'nsmap'): # lxml loaded for prefix, namespace in schema_elem.nsmap.items(): self.namespaces[prefix or ''] = namespace # Change None key with '' else: # xml.etree.ElementTree loaded: need to get namespaces from file for event, node in ElementTree.iterparse(self._xsd_file, events=['start-ns']): self.namespaces[node[0]] = node[1] logger.debug('Namespaces: {0}'.format(self.namespaces)) # Set namespace prefix for schema declarations for prefix in self.namespaces: if self.namespaces[prefix] == self.target_namespace: self.target_prefix = prefix if prefix: prefix = '%s:' % prefix break else: prefix = '' logger.debug("Use prefix '%s' for schema declarations" % prefix) # Build lookup maps using XSD declarations logger.debug("### Add global simple types ###") add_xsd_types_to_dict(self.findall('./xsd:simpleType'), self.types, xsd_simple_type_factory, xsd_types=self.types, prefix=prefix) logger.debug("### Add global attributes ###") counter = 0 for elem in self.findall('./xsd:attributes'): self.attributes.update([ xsd_attribute_type_factory(elem, xsd_types=self.types, prefix=prefix) ]) counter += 1 logger.debug("%d global attributes added" % counter) logger.debug("### Add attribute groups ###") counter = 0 for elem in self.findall('./xsd:attributeGroup'): try: name = elem.attrib['name'] except KeyError: raise XMLSchemaValidationError( "Missing 'name' attribute for {}".format(elem)) if name in self.attribute_groups: raise XMLSchemaValidationError( "Duplicate attributeGroup: {}".format(name)) self.attribute_groups[name] = OrderedDict([ xsd_attribute_type_factory(child, xsd_types=self.types, prefix=prefix) for child in elem if child.tag == _ATTRIBUTE_TAG ]) counter += 1 logger.debug("%d attribute groups added" % counter) logger.debug("### Add global complex types ###") add_xsd_types_to_dict(self.findall('./xsd:complexType'), self.types, xsd_complex_type_factory, xsd_types=self.types, prefix=prefix, xsd_attributes=self.attributes) logger.debug("### Add content model groups ###") counter = 0 for elem in self.findall('./xsd:group'): try: name = elem.attrib['name'] except KeyError: raise XMLSchemaValidationError( "Missing 'name' attribute for {}".format(elem)) if name in self.groups: raise XMLSchemaValidationError( "Duplicate group: {}".format(name)) from .xsdtypes import xsd_group_factory self.groups[name] = xsd_group_factory( elem, xsd_groups=self.groups, xsd_types=self.types, xsd_attributes=self.attributes, xsd_attribute_groups=self.attribute_groups) counter += 1 logger.debug("%d XSD named groups added" % counter) logger.debug("### Add elements starting from root element(s) ###") for elem in self.findall('./xsd:element'): xsd_element_factory(elem, parent_path=None, prefix=prefix, xsd_elements=self.elements, xsd_types=self.types, xsd_attributes=self.attributes, xsd_attribute_groups=self.attribute_groups) logger.debug("%d XSD elements added" % len(self.elements))