示例#1
0
    def create_default_attribute(cls, item: Class, extension: Extension):
        if extension.type.native_code == DataType.ANY_TYPE.code:
            attr = Attr(
                name="any_element",
                local_name="any_element",
                index=0,
                wildcard=True,
                default=list if extension.restrictions.is_list else None,
                types=[extension.type.clone()],
                local_type=TagType.ANY,
                namespace=NamespaceType.ANY.value,
                restrictions=extension.restrictions.clone(),
            )
        else:
            attr = Attr(
                name="value",
                local_name="value",
                index=0,
                default=None,
                types=[extension.type.clone()],
                local_type=TagType.EXTENSION,
                restrictions=extension.restrictions.clone(),
            )

        item.attrs.insert(0, attr)
        item.extensions.remove(extension)
示例#2
0
    def sanitize_attribute(cls, attr: Attr):
        if attr.is_list:
            attr.fixed = False
        else:
            attr.restrictions.sequential = False

        if attr.is_optional or attr.is_xsi_type:
            attr.fixed = False
            attr.default = None
示例#3
0
    def process_attribute(cls, target: Class, attr: Attr, parents: List[str]):
        """Normalize attribute properties."""
        attr.name = cls.attribute_name(attr.name)
        attr.display_type = cls.attribute_display_type(attr, parents)
        attr.default = cls.attribute_default(attr, target.ns_map)
        attr.xml_type = cls.xml_type_map.get(attr.tag)

        if attr.local_name:
            attr.local_name = text.suffix(attr.local_name)
示例#4
0
    def build_class_attribute(self, target: Class, obj: ElementBase,
                              parent_restrictions: Restrictions):
        """Generate and append an attribute target to the target class."""
        types = self.build_class_attribute_types(target, obj)
        restrictions = Restrictions.from_element(obj)

        if obj.class_name in (Tag.ELEMENT, Tag.ANY):
            restrictions.merge(parent_restrictions)

        if restrictions.prohibited:
            return

        name = obj.real_name
        target.ns_map.update(obj.ns_map)

        target.attrs.append(
            Attr(
                index=obj.index,
                name=name,
                local_name=name,
                default=obj.default_value,
                fixed=obj.is_fixed,
                types=types,
                tag=obj.class_name,
                help=obj.display_help,
                namespace=self.element_namespace(obj),
                restrictions=restrictions,
            ))
示例#5
0
    def clone_attribute(cls,
                        attr: Attr,
                        restrictions: Restrictions,
                        prefix: Optional[str] = None):
        clone = attr.clone()
        clone.restrictions.merge(restrictions)
        if prefix:
            for attr_type in clone.types:
                if not attr_type.native and attr_type.name.find(":") == -1:
                    attr_type.name = f"{prefix}:{attr_type.name}"

        return clone
示例#6
0
    def create_mixed_attribute(cls, target: Class):
        if not target.mixed or target.has_wild_attr:
            return

        attr = Attr(
            name="content",
            local_name="content",
            index=0,
            types=[AttrType(name=DataType.ANY_TYPE.code, native=True)],
            tag=Tag.ANY,
            namespace=NamespaceType.ANY.value,
        )
        target.attrs.insert(0, attr)
示例#7
0
    def flatten_attribute_types(self, target: Class, attr: Attr):
        """
        Flatten attribute types by using the source attribute type.

        Steps:
            * Skip xsd native types
            * Detect circular references if no source is found
            * Skip enumeration types
            * Overwrite attribute type from source
        """
        types = []
        for attr_type in attr.types:
            source = None
            if not attr_type.native:
                type_qname = target.source_qname(attr_type.name)
                source = self.find_class(type_qname)

            if source is None:
                attr_type.self_ref = self.attr_depends_on(attr_type, target)
                types.append(attr_type)
            elif self.is_qname(source):
                types.append(source.extensions[0].type.clone())
            elif source.is_enumeration:
                types.append(attr_type)
            elif len(source.attrs) == 1:
                source_attr = source.attrs[0]
                types.extend(source_attr.types)
                restrictions = source_attr.restrictions.clone()
                restrictions.merge(attr.restrictions)
                attr.restrictions = restrictions
                self.copy_inner_classes(source, target)
            else:
                types.append(AttrType(name=DataType.STRING.code, native=True))
                logger.warning("Missing type implementation: %s",
                               source.type.__name__)

        attr.types = types
示例#8
0
    def create_reference_attribute(cls, source: Class, qname: QName):
        prefix = None
        if qname.namespace != source.source_namespace:
            prefix = source.source_prefix

        reference = f"{prefix}:{source.name}" if prefix else source.name
        return Attr(
            name=source.name,
            local_name=source.name,
            index=0,
            default=None,
            types=[AttrType(name=reference)],
            local_type=source.type.__name__,
            namespace=source.namespace,
        )
示例#9
0
    def flatten_attribute_types(self, target: Class, attr: Attr):
        """
        Loop over the the given attribute types to flatten simple definitions.

        Notes:
            * xs:pattern is not yet supported reset all native types to xs:string.
            * skip over forward references aka inner classes
        """
        for current_type in list(attr.types):
            if current_type.native:
                if attr.restrictions.pattern:
                    self.reset_attribute_type(current_type)
            elif not current_type.forward_ref:
                self.flatten_attribute_type(target, attr, current_type)

        attr.types = unique_sequence(attr.types, key="name")
示例#10
0
    def merge_attribute_type(cls, source: Class, target: Class, attr: Attr,
                             attr_type: AttrType):
        if len(source.attrs) != 1:
            logger.warning("Missing implementation: %s", source.type.__name__)
            cls.reset_attribute_type(attr_type)
        else:
            source_attr = source.attrs[0]
            index = attr.types.index(attr_type)
            attr.types.pop(index)

            for source_attr_type in source_attr.types:
                clone_type = source_attr_type.clone()
                attr.types.insert(index, clone_type)
                index += 1

            restrictions = source_attr.restrictions.clone()
            restrictions.merge(attr.restrictions)
            attr.restrictions = restrictions
            cls.copy_inner_classes(source, target)