def extend(self, base):
        """Create a new complextype instance which is the current type
        extending the given base type.

        Used for handling xsd:extension tags

        TODO: Needs a rewrite where the child containers are responsible for
        the extend functionality.

        """
        if isinstance(base, ComplexType):
            base_attributes = base._attributes_unwrapped
            base_element = base._element
        else:
            base_attributes = []
            base_element = None
        attributes = base_attributes + self._attributes_unwrapped

        # Make sure we don't have duplicate (child is leading)
        if base_attributes and self._attributes_unwrapped:
            new_attributes = OrderedDict()
            for attr in attributes:
                if isinstance(attr, AnyAttribute):
                    new_attributes['##any'] = attr
                else:
                    new_attributes[attr.qname.text] = attr
            attributes = new_attributes.values()

        # If the base and the current type both have an element defined then
        # these need to be merged. The base_element might be empty (or just
        # container a placeholder element).
        element = []
        if self._element and base_element:
            self._element = self._element.resolve()
            base_element = base_element.resolve()

            element = self._element.clone(self._element.name)
            if isinstance(base_element, OrderIndicator):
                if isinstance(self._element, Choice):
                    element = base_element.clone(self._element.name)
                    element.append(self._element)
                elif isinstance(element, OrderIndicator):
                    for item in reversed(base_element):
                        element.insert(0, item)

            elif isinstance(self._element, Group):
                raise NotImplementedError('TODO')
            else:
                pass  # Element (ignore for now)

        elif self._element or base_element:
            element = self._element or base_element
        else:
            element = Element('_value_1', base)

        new = self.__class__(element=element,
                             attributes=attributes,
                             qname=self.qname,
                             is_global=self.is_global)
        return new
Example #2
0
    def elements_nested(self):
        """List of tuples containing the element name and the element"""
        result = []
        generator = NamePrefixGenerator()

        if self._extension:
            name = generator.get_name()
            if not hasattr(self._extension, 'elements_nested'):
                result.append((name, Element(name, self._extension)))
            else:
                result.extend(self._extension.elements_nested)

        if self._restriction and not self._element:
            # So this is a workaround to support wsdl:arrayType. This doesn't
            # actually belong here but for now it's the easiest way to achieve
            # this. What this does it that is checks if the restriction
            # contains an arrayType attribute and then use that to retrieve
            # the xsd type for the array. (We ignore AnyAttributes here)
            attrs = {
                attr.qname.text: attr
                for attr in self._attributes if attr.qname
            }
            array_type = attrs.get(
                '{http://schemas.xmlsoap.org/soap/encoding/}arrayType')
            if array_type:
                name = generator.get_name()
                result.append((name,
                               Sequence([
                                   Any(max_occurs='unbounded',
                                       restrict=array_type.array_type)
                               ])))
            else:
                name = generator.get_name()
                if not hasattr(self._restriction, 'elements_nested'):
                    result.append((name, Element(name, self._restriction)))
                else:
                    result.extend(self._restriction.elements_nested)

        # _element is one of All, Choice, Group, Sequence
        if self._element:
            result.append((generator.get_name(), self._element))
        return result
Example #3
0
    def elements_nested(self):
        """List of tuples containing the element name and the element"""
        result = []
        generator = NamePrefixGenerator()

        if self._extension:
            name = generator.get_name()
            if not hasattr(self._extension, 'elements_nested'):
                result.append((name, Element(name, self._extension)))
            else:
                result.extend(self._extension.elements_nested)

        if self._restriction:
            name = generator.get_name()
            if not hasattr(self._restriction, 'elements_nested'):
                result.append((name, Element(name, self._restriction)))
            else:
                result.extend(self._restriction.elements_nested)

        # _element is one of All, Choice, Group, Sequence
        if self._element:
            result.append((generator.get_name(), self._element))
        return result
Example #4
0
    def extend(self, base):
        """Create a new complextype instance which is the current type
        extending the given base type.

        Used for handling xsd:extension tags

        """
        if isinstance(base, ComplexType):
            base_attributes = base._attributes_unwrapped
            base_element = base._element
        else:
            base_attributes = []
            base_element = None
        attributes = base_attributes + self._attributes_unwrapped

        # Make sure we don't have duplicate (child is leading)
        if base_attributes and self._attributes_unwrapped:
            new_attributes = OrderedDict()
            for attr in attributes:
                if isinstance(attr, AnyAttribute):
                    new_attributes['##any'] = attr
                else:
                    new_attributes[attr.qname.text] = attr
            attributes = new_attributes.values()

        element = []
        if self._element and base_element:
            element = self._element.clone(self._element.name)
            if isinstance(element, OrderIndicator):
                for item in reversed(base_element):
                    element.insert(0, item)

            elif isinstance(self._element, Group):
                raise NotImplementedError('TODO')

        elif self._element or base_element:
            element = self._element or base_element
        else:
            element = Element('_value_1', base)

        new = self.__class__(
            element=element,
            attributes=attributes,
            qname=self.qname)
        return new
Example #5
0
    def resolve(self, schema):
        children = []
        for elm in self._children:
            if isinstance(elm, RefElement):
                elm = elm._elm

            if isinstance(elm, UnresolvedType):
                xsd_type = elm.resolve(schema)
                if isinstance(xsd_type, SimpleType):
                    children.append(Element(None, xsd_type))
                else:
                    children.extend(list(xsd_type._children))

            elif isinstance(elm, GroupElement):
                children.extend(list(elm))
            else:
                children.append(elm)
        self._children = children
        return self