XSDNativeSimpleTypeMapping.py 2.83 KB
Newer Older
canterburym's avatar
canterburym committed
import logging

from xmlschema.validators.simple_types import *
from xmlschema.validators.complex_types import *
from xmlschema.validators.groups import *
from xmlschema.validators.facets import *

from .TypeMapping import TypeMapping
from .SimpleTypeMapping import SimpleTypeMapping

log = logging.getLogger()

class XSDNativeSimpleTypeMapping(SimpleTypeMapping):

    def map(self, xst: BaseXsdType):
        log.debug(f"Attempting mapping of {xst} to XSD native type")
        j = super().map(xst)
        if j is None:
            log.debug("Not a simple type, giving up")
            return None

        mapped_type = TypeMapping.XSD_TYPE_MAP.get(xst.base_type.local_name)
        parent_type = None

        if mapped_type is None:
            ns = TypeMapping.extract_namespace(xst.base_type.name)
            if ns == XSDNativeSimpleTypeMapping.XSD_NS:
                print (xst)
                print (xst.base_type)
                raise Exception (f"No mapping for xs:{xst.base_type.local_name}")
            if len(xst.facets) == 0:
                mapped_type = TypeMapping.get_ref_for(xst.base_type, xst.namespaces[''])
            else:
                parent_type = TypeMapping.get_ref_for(xst.base_type, xst.namespaces[''])
                mapped_type = TypeMapping.XSD_TYPE_MAP.get(xst.root_type.local_name)
                if mapped_type is None:
                    raise Exception (f"Could not find mapping for root type xs:{xst.root_type.local_name}")

        mapped_type = dict(mapped_type)
        
        for k, v in xst.facets.items():
            log.debug(f"Mapping facet {v}")
            if type(v) is XsdMaxLengthFacet:
                mapped_type['maxLength'] = v.value
                continue
            if type(v) is XsdMinLengthFacet:
                mapped_type['minLength'] = v.value
                continue
            if type(v) is XsdPatternFacets:
                if len(v.regexps) > 1:
                    raise Exception (f"Multiple patterns given in facet {v} of {xst}")
                p = v.regexps[0]
                if (not p.startswith('^')) and (not p.endswith('$')):
                    p = f"^{p}$"
                mapped_type['pattern'] = p
                continue
            if type (v) is XsdMinInclusiveFacet:
                mapped_type['minimum'] = v.value
                continue
            if type (v) is XsdMaxInclusiveFacet:
                mapped_type['maximum'] = v.value
                continue
            if type (v) is XsdMinExclusiveFacet:
                mapped_type['exclusiveMinimum'] = v.value
                continue
            if type (v) is XsdMaxExclusiveFacet:
                mapped_type['exclusiveMaximum'] = v.value
                continue
            raise Exception (f"Unhandled facet {v}")
        if parent_type:
            return { 'allOf' : [parent_type, mapped_type] }
        return mapped_type