Ejemplo n.º 1
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Choose out of multiple
            options = []
            for element_name, element in self.elements_nested:

                local_xmlelements = copy.copy(xmlelements)

                try:
                    sub_result = element.parse_xmlelements(
                        xmlelements=local_xmlelements,
                        schema=schema,
                        name=element_name,
                        context=context)
                except UnexpectedElementError:
                    continue

                if isinstance(element, Element):
                    sub_result = {element_name: sub_result}

                num_consumed = len(xmlelements) - len(local_xmlelements)
                if num_consumed:
                    options.append((num_consumed, sub_result))

            if not options:
                xmlelements = []
                break

            # Sort on least left
            options = sorted(options, key=operator.itemgetter(0), reverse=True)
            if options:
                result.append(options[0][1])
                for i in range(options[0][0]):
                    xmlelements.popleft()
            else:
                break

        if self.accepts_multiple:
            result = {name: result}
        else:
            result = result[0] if result else {}
        return result
Ejemplo n.º 2
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            result.append(
                self.child.parse_xmlelements(
                    xmlelements, schema, name, context=context)
            )
            if not xmlelements:
                break
        if not self.accepts_multiple and result:
            return result[0]
        return {name: result}
Ejemplo n.º 3
0
    def render(self, parent, value, render_path):
        """Create subelements in the given parent object."""
        if not isinstance(value, list):
            values = [value]
        else:
            values = value

        self.validate(values, render_path)

        for value in max_occurs_iter(self.max_occurs, values):
            for name, element in self.elements_nested:
                if name:
                    if name in value:
                        element_value = value[name]
                        child_path = render_path + [name]
                    else:
                        element_value = NotSet
                        child_path = render_path
                else:
                    element_value = value
                    child_path = render_path

                if element_value is SkipValue:
                    continue

                if element_value is not None or not element.is_optional:
                    element.render(parent, element_value, child_path)
Ejemplo n.º 4
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them"""
        result = []
        for i in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Workaround for SOAP servers which incorrectly use unqualified
            # or qualified elements in the responses (#170, #176). To make the
            # best of it we compare the full uri's if both elements have a
            # namespace. If only one has a namespace then only compare the
            # localname.

            # If both elements have a namespace and they don't match then skip
            element_tag = etree.QName(xmlelements[0].tag)
            if (
                element_tag.namespace and self.qname.namespace and
                element_tag.namespace != self.qname.namespace
            ):
                break

            # Only compare the localname
            if element_tag.localname == self.qname.localname:
                xmlelement = xmlelements.pop(0)
                item = self.parse(
                    xmlelement, schema, allow_none=True, context=context)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 5
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :return: dict or None

        """
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            if xmlelements:
                xmlelement = xmlelements.popleft()
                item = self.parse(xmlelement, schema, context=context)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 6
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            result.append(
                self.child.parse_xmlelements(xmlelements,
                                             schema,
                                             name,
                                             context=context))
            if not xmlelements:
                break
        if not self.accepts_multiple and result:
            return result[0]
        return {name: result}
Ejemplo n.º 7
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Choose out of multiple
            options = []
            for element_name, element in self.elements_nested:

                local_xmlelements = copy.copy(xmlelements)

                try:
                    sub_result = element.parse_xmlelements(
                        xmlelements=local_xmlelements,
                        schema=schema,
                        name=element_name,
                        context=context)
                except UnexpectedElementError:
                    continue

                if isinstance(element, Element):
                    sub_result = {element_name: sub_result}

                num_consumed = len(xmlelements) - len(local_xmlelements)
                if num_consumed:
                    options.append((num_consumed, sub_result))

            if not options:
                xmlelements = []
                break

            # Sort on least left
            options = sorted(options, key=operator.itemgetter(0), reverse=True)
            if options:
                result.append(options[0][1])
                for i in range(options[0][0]):
                    xmlelements.popleft()
            else:
                break

        if self.accepts_multiple:
            result = {name: result}
        else:
            result = result[0] if result else {}
        return result
Ejemplo n.º 8
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :return: dict or None

        """
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            if xmlelements:
                xmlelement = xmlelements.popleft()
                item = self.parse(xmlelement, schema, context=context)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 9
0
    def render(self, parent, value):
        """Create subelements in the given parent object.

        To make sure we render values only once the value items are copied
        and the rendered attribute is removed from it once it is rendered.

        """
        if not isinstance(value, list):
            values = [value]
        else:
            values = value

        for i, value in zip(max_occurs_iter(self.max_occurs), values):
            value = copy.copy(value)

            for name, element in self.elements_nested:
                if name:
                    if name in value:
                        element_value = value[name]
                        del value[name]
                    else:
                        element_value = None
                else:
                    element_value = value
                if element_value is not None or not element.is_optional:
                    element.render(parent, element_value)
Ejemplo n.º 10
0
    def render(self, parent, value, render_path):
        """Create subelements in the given parent object."""
        if not isinstance(value, list):
            values = [value]
        else:
            values = value

        self.validate(values, render_path)

        for value in max_occurs_iter(self.max_occurs, values):
            for name, element in self.elements_nested:
                if name:
                    if name in value:
                        element_value = value[name]
                        child_path = render_path + [name]
                    else:
                        element_value = NotSet
                        child_path = render_path
                else:
                    element_value = value
                    child_path = render_path

                if element_value is SkipValue:
                    continue

                if element_value is not None or not element.is_optional:
                    element.render(parent, element_value, child_path)
Ejemplo n.º 11
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        result = []
        for item in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            item_result = OrderedDict()
            for elm_name, element in self.elements:
                item_subresult = element.parse_xmlelements(
                    xmlelements, schema, name, context=context)

                # Unwrap if allowed
                if isinstance(element, OrderIndicator):
                    item_result.update(item_subresult)
                else:
                    item_result[elm_name] = item_subresult

                if not xmlelements:
                    break
            if item_result:
                result.append(item_result)

        if not self.accepts_multiple:
            return result[0] if result else None

        return {name: result}
Ejemplo n.º 12
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        result = []
        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            item_result = OrderedDict()
            for elm_name, element in self.elements:
                item_subresult = element.parse_xmlelements(xmlelements,
                                                           schema,
                                                           name,
                                                           context=context)

                # Unwrap if allowed
                if isinstance(element, OrderIndicator):
                    item_result.update(item_subresult)
                else:
                    item_result[elm_name] = item_subresult

                if not xmlelements:
                    break
            if item_result:
                result.append(item_result)

        if not self.accepts_multiple:
            return result[0] if result else None

        return {name: result}
Ejemplo n.º 13
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        if self.accepts_multiple:
            if name not in kwargs:
                return {}, kwargs

            available_kwargs.remove(name)
            item_kwargs = kwargs[name]

            result = []
            sub_name = '_value_1' if self.child.accepts_multiple else None
            for sub_kwargs in max_occurs_iter(self.max_occurs, item_kwargs):
                available_sub_kwargs = set(sub_kwargs.keys())
                subresult = self.child.parse_kwargs(sub_kwargs, sub_name,
                                                    available_sub_kwargs)

                if available_sub_kwargs:
                    raise TypeError(
                        ("%s() got an unexpected keyword argument %r.") %
                        (self, list(available_sub_kwargs)[0]))

                if subresult:
                    result.append(subresult)
            if result:
                result = {name: result}
        else:
            result = self.child.parse_kwargs(kwargs, name, available_kwargs)
        return result
Ejemplo n.º 14
0
    def render(self, parent, value):
        """Create subelements in the given parent object.

        To make sure we render values only once the value items are copied
        and the rendered attribute is removed from it once it is rendered.

        """
        if not isinstance(value, list):
            values = [value]
        else:
            values = value

        for i, value in zip(max_occurs_iter(self.max_occurs), values):
            value = copy.copy(value)

            for name, element in self.elements_nested:
                if name:
                    if name in value:
                        element_value = value[name]
                        del value[name]
                    else:
                        element_value = None
                else:
                    element_value = value
                if element_value is not None or not element.is_optional:
                    element.render(parent, element_value)
Ejemplo n.º 15
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        if self.accepts_multiple:
            if name not in kwargs:
                return {}

            available_kwargs.remove(name)
            item_kwargs = kwargs[name]

            result = []
            sub_name = '_value_1' if self.child.accepts_multiple else None
            for sub_kwargs in max_occurs_iter(self.max_occurs, item_kwargs):
                available_sub_kwargs = set(sub_kwargs.keys())
                subresult = self.child.parse_kwargs(
                    sub_kwargs, sub_name, available_sub_kwargs)

                if available_sub_kwargs:
                    raise TypeError((
                        "%s() got an unexpected keyword argument %r."
                    ) % (self, list(available_sub_kwargs)[0]))

                if subresult:
                    result.append(subresult)
            if result:
                result = {name: result}
        else:
            result = self.child.parse_kwargs(kwargs, name, available_kwargs)
        return result
Ejemplo n.º 16
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them"""
        result = []
        for i in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Workaround for SOAP servers which incorrectly use unqualified
            # or qualified elements in the responses (#170, #176). To make the
            # best of it we compare the full uri's if both elements have a
            # namespace. If only one has a namespace then only compare the
            # localname.

            # If both elements have a namespace and they don't match then skip
            element_tag = etree.QName(xmlelements[0].tag)
            if (element_tag.namespace and self.qname.namespace
                    and element_tag.namespace != self.qname.namespace):
                break

            # Only compare the localname
            if element_tag.localname == self.qname.localname:
                xmlelement = xmlelements.pop(0)
                item = self.parse(xmlelement,
                                  schema,
                                  allow_none=True,
                                  context=context)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 17
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        """Apply the given kwarg to the element.

        The available_kwargs is modified in-place. Returns a dict with the
        result.

        """
        if self.accepts_multiple:
            assert name

        if name:
            if name not in available_kwargs:
                return {}

            assert self.accepts_multiple

            # Make sure we have a list, lame lame
            item_kwargs = kwargs.get(name)
            if not isinstance(item_kwargs, list):
                item_kwargs = [item_kwargs]

            result = []
            for item_value in max_occurs_iter(self.max_occurs, item_kwargs):
                try:
                    item_kwargs = set(item_value.keys())
                except AttributeError:
                    raise TypeError(
                        "A list of dicts is expected for unbounded Sequences")

                subresult = OrderedDict()
                for item_name, element in self.elements:
                    value = element.parse_kwargs(item_value, item_name, item_kwargs)
                    if value is not None:
                        subresult.update(value)

                if item_kwargs:
                    raise TypeError((
                        "%s() got an unexpected keyword argument %r."
                    ) % (self, list(item_kwargs)[0]))

                result.append(subresult)

            result = {name: result}

            # All items consumed
            if not any(filter(None, item_kwargs)):
                available_kwargs.remove(name)

            return result

        else:
            assert not self.accepts_multiple
            result = OrderedDict()
            for elm_name, element in self.elements_nested:
                sub_result = element.parse_kwargs(kwargs, elm_name, available_kwargs)
                if sub_result:
                    result.update(sub_result)

            return result
Ejemplo n.º 18
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        if schema is not None and schema.settings.xsd_ignore_sequence_order:
            self.elements = sorted(self.elements, key=lambda e: isinstance(e[1], Any))
            reordered_elements = sorted(xmlelements, key=lambda e: {k: v for v, k in enumerate(
                [x[1].name for x in self.elements])}.get(etree.QName(e.tag).localname, len(xmlelements)))
            xmlelements.clear()
            xmlelements.extend(reordered_elements)

        if self.accepts_multiple:
            assert name

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            item_result = OrderedDict()
            for elm_name, element in self.elements:
                try:
                    item_subresult = element.parse_xmlelements(
                        xmlelements, schema, name, context=context)
                except UnexpectedElementError:
                    if schema.settings.strict:
                        raise
                    item_subresult = None

                # Unwrap if allowed
                if isinstance(element, OrderIndicator):
                    item_result.update(item_subresult)
                else:
                    item_result[elm_name] = item_subresult

                if not xmlelements:
                    break
            if item_result:
                result.append(item_result)

        if not self.accepts_multiple:
            return result[0] if result else None
        return {name: result}
Ejemplo n.º 19
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        result = []

        for i in max_occurs_iter(self.max_occurs):
            result.append(
                self.child.parse_xmlelements(
                    xmlelements, schema, name, context=context)
            )
        if not self.accepts_multiple and result:
            return result[0]
        return {name: result}
Ejemplo n.º 20
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        result = []

        for i in max_occurs_iter(self.max_occurs):
            result.append(
                self.child.parse_xmlelements(
                    xmlelements, schema, name, context=context)
            )
        if not self.accepts_multiple and result:
            return result[0]
        return {name: result}
Ejemplo n.º 21
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :return: dict or None

        """
        result = []
        num_matches = 0
        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Workaround for SOAP servers which incorrectly use unqualified
            # or qualified elements in the responses (#170, #176). To make the
            # best of it we compare the full uri's if both elements have a
            # namespace. If only one has a namespace then only compare the
            # localname.

            # If both elements have a namespace and they don't match then skip
            element_tag = etree.QName(xmlelements[0].tag)
            if (
                element_tag.namespace and self.qname.namespace and
                element_tag.namespace != self.qname.namespace and
                schema.strict
            ):
                break

            # Only compare the localname
            if element_tag.localname == self.qname.localname:
                xmlelement = xmlelements.popleft()
                num_matches += 1
                item = self.parse(
                    xmlelement, schema, allow_none=True, context=context)
                result.append(item)
            else:
                # If the element passed doesn't match and the current one is
                # not optional then throw an error
                if num_matches == 0 and not self.is_optional:
                    raise UnexpectedElementError(
                        "Unexpected element %r, expected %r" % (
                            element_tag.text, self.qname.text))
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 22
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :return: dict or None

        """
        result = []
        num_matches = 0
        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Workaround for SOAP servers which incorrectly use unqualified
            # or qualified elements in the responses (#170, #176). To make the
            # best of it we compare the full uri's if both elements have a
            # namespace. If only one has a namespace then only compare the
            # localname.

            # If both elements have a namespace and they don't match then skip
            element_tag = etree.QName(xmlelements[0].tag)
            if (
                element_tag.namespace and self.qname.namespace and
                element_tag.namespace != self.qname.namespace and
                schema.settings.strict
            ):
                break

            # Only compare the localname
            if element_tag.localname == self.qname.localname:
                xmlelement = xmlelements.popleft()
                num_matches += 1
                item = self.parse(
                    xmlelement, schema, allow_none=True, context=context)
                result.append(item)
            else:
                # If the element passed doesn't match and the current one is
                # not optional then throw an error
                if num_matches == 0 and not self.is_optional:
                    raise UnexpectedElementError(
                        "Unexpected element %r, expected %r" % (
                            element_tag.text, self.qname.text))
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 23
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        """Apply the given kwarg to the element.

        The available_kwargs is modified in-place. Returns a dict with the
        result.

        """
        if self.accepts_multiple:
            assert name

        if name and name in available_kwargs:

            # Make sure we have a list, lame lame
            item_kwargs = kwargs.get(name)
            if not isinstance(item_kwargs, list):
                item_kwargs = [item_kwargs]

            result = []
            for i, item_value in zip(max_occurs_iter(self.max_occurs),
                                     item_kwargs):
                item_kwargs = set(item_value.keys())
                subresult = OrderedDict()
                for item_name, element in self.elements:
                    value = element.parse_kwargs(item_value, item_name,
                                                 item_kwargs)
                    if value is not None:
                        subresult.update(value)

                result.append(subresult)

            if self.accepts_multiple:
                result = {name: result}
            else:
                result = result[0] if result else None

            # All items consumed
            if not any(filter(None, item_kwargs)):
                available_kwargs.remove(name)

            return result

        else:
            result = OrderedDict()
            for elm_name, element in self.elements:
                sub_result = element.parse_kwargs(kwargs, elm_name,
                                                  available_kwargs)
                if sub_result is not None:
                    result.update(sub_result)

            if name:
                result = {name: result}

            return result
Ejemplo n.º 24
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Return a dictionary"""
        result = []

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            for node in list(xmlelements):

                # Choose out of multiple
                options = []
                for element_name, element in self.elements_nested:

                    local_xmlelements = copy.copy(xmlelements)

                    try:
                        sub_result = element.parse_xmlelements(
                            local_xmlelements, schema, context=context)
                    except UnexpectedElementError:
                        continue

                    if isinstance(element, OrderIndicator):
                        if element.accepts_multiple:
                            sub_result = {element_name: sub_result}
                    else:
                        sub_result = {element_name: sub_result}

                    num_consumed = len(xmlelements) - len(local_xmlelements)
                    if num_consumed:
                        options.append((num_consumed, sub_result))

                if not options:
                    xmlelements = []
                    break

                # Sort on least left
                options = sorted(options,
                                 key=operator.itemgetter(0),
                                 reverse=True)
                if options:
                    result.append(options[0][1])
                    for i in range(options[0][0]):
                        xmlelements.popleft()
                else:
                    break

        if self.accepts_multiple:
            result = {name: result}
        else:
            result = result[0] if result else {}
        return result
Ejemplo n.º 25
0
    def parse_kwargs(self, kwargs, name=None):
        """Apply the given kwarg to the element.

        Returns a tuple with two dictionaries, the first one being the result
        and the second one the unparsed kwargs.

        """
        if self.accepts_multiple:
            assert name

        if name and name in kwargs:

            # Make sure we have a list, lame lame
            item_kwargs = kwargs.get(name)
            if not isinstance(item_kwargs, list):
                item_kwargs = [item_kwargs]

            result = []
            for i, item_value in zip(max_occurs_iter(self.max_occurs),
                                     item_kwargs):
                subresult = OrderedDict()
                for item_name, element in self.elements:
                    value, item_value = element.parse_kwargs(
                        item_value, item_name)
                    if value is not None:
                        subresult.update(value)

                result.append(subresult)

            if self.accepts_multiple:
                result = {name: result}
            else:
                result = result[0] if result else None

            # All items consumed
            if not any(filter(None, item_kwargs)):
                del kwargs[name]

            return result, kwargs

        else:
            result = OrderedDict()
            for elm_name, element in self.elements:
                sub_result, kwargs = element.parse_kwargs(kwargs, elm_name)
                if sub_result is not None:
                    result.update(sub_result)

            if name:
                result = {name: result}

            return result, kwargs
Ejemplo n.º 26
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        """Apply the given kwarg to the element.

        The available_kwargs is modified in-place. Returns a dict with the
        result.

        """
        if self.accepts_multiple:
            assert name

        if name and name in available_kwargs:

            # Make sure we have a list, lame lame
            item_kwargs = kwargs.get(name)
            if not isinstance(item_kwargs, list):
                item_kwargs = [item_kwargs]

            result = []
            for i, item_value in zip(max_occurs_iter(self.max_occurs), item_kwargs):
                item_kwargs = set(item_value.keys())
                subresult = OrderedDict()
                for item_name, element in self.elements:
                    value = element.parse_kwargs(item_value, item_name, item_kwargs)
                    if value is not None:
                        subresult.update(value)

                result.append(subresult)

            if self.accepts_multiple:
                result = {name: result}
            else:
                result = result[0] if result else None

            # All items consumed
            if not any(filter(None, item_kwargs)):
                available_kwargs.remove(name)

            return result

        else:
            result = OrderedDict()
            for elm_name, element in self.elements_nested:
                sub_result = element.parse_kwargs(kwargs, elm_name, available_kwargs)
                if sub_result:
                    result.update(sub_result)

            if name:
                result = {name: result}

            return result
Ejemplo n.º 27
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Return a dictionary"""
        result = []

        for i in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            for node in list(xmlelements):

                # Choose out of multiple
                options = []
                for element_name, element in self.elements_nested:

                    local_xmlelements = copy.copy(xmlelements)

                    try:
                        sub_result = element.parse_xmlelements(
                            local_xmlelements, schema, context=context)
                    except UnexpectedElementError:
                        continue

                    if isinstance(element, OrderIndicator):
                        if element.accepts_multiple:
                            sub_result = {element_name: sub_result}
                    else:
                        sub_result = {element_name: sub_result}

                    num_consumed = len(xmlelements) - len(local_xmlelements)
                    if num_consumed:
                        options.append((num_consumed, sub_result))

                if not options:
                    xmlelements = []
                    break

                # Sort on least left
                options = sorted(options, key=operator.itemgetter(0), reverse=True)
                if options:
                    result.append(options[0][1])
                    for i in range(options[0][0]):
                        xmlelements.popleft()
                else:
                    break

        if self.accepts_multiple:
            result = {name: result}
        else:
            result = result[0] if result else {}
        return result
Ejemplo n.º 28
0
    def parse_kwargs(self, kwargs, name=None):
        """Apply the given kwarg to the element.

        Returns a tuple with two dictionaries, the first one being the result
        and the second one the unparsed kwargs.

        """
        if self.accepts_multiple:
            assert name

        if name and name in kwargs:

            # Make sure we have a list, lame lame
            item_kwargs = kwargs.get(name)
            if not isinstance(item_kwargs, list):
                item_kwargs = [item_kwargs]

            result = []
            for i, item_value in zip(max_occurs_iter(self.max_occurs), item_kwargs):
                subresult = OrderedDict()
                for item_name, element in self.elements:
                    value, item_value = element.parse_kwargs(item_value, item_name)
                    if value is not None:
                        subresult.update(value)

                result.append(subresult)

            if self.accepts_multiple:
                result = {name: result}
            else:
                result = result[0] if result else None

            # All items consumed
            if not any(filter(None, item_kwargs)):
                del kwargs[name]

            return result, kwargs

        else:
            result = OrderedDict()
            for elm_name, element in self.elements:
                sub_result, kwargs = element.parse_kwargs(kwargs, elm_name)
                if sub_result is not None:
                    result.update(sub_result)

            if name:
                result = {name: result}

            return result, kwargs
Ejemplo n.º 29
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        if self.accepts_multiple:
            assert name

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            item_result = OrderedDict()
            for elm_name, element in self.elements:
                try:
                    item_subresult = element.parse_xmlelements(xmlelements,
                                                               schema,
                                                               name,
                                                               context=context)
                except UnexpectedElementError:
                    if schema.settings.strict:
                        raise
                    item_subresult = None

                # Unwrap if allowed
                if isinstance(element, OrderIndicator):
                    item_result.update(item_subresult)
                else:
                    item_result[elm_name] = item_subresult

                if not xmlelements:
                    break
            if item_result:
                result.append(item_result)

        if not self.accepts_multiple:
            return result[0] if result else None
        return {name: result}
Ejemplo n.º 30
0
    def parse_xmlelements(self, xmlelements, schema, name=None):
        result = []

        for i in max_occurs_iter(self.max_occurs):
            if xmlelements:
                xmlelement = xmlelements.pop(0)
                item = self.parse(xmlelement, schema)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 31
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them"""
        result = []

        for i in max_occurs_iter(self.max_occurs):
            if xmlelements:
                xmlelement = xmlelements.pop(0)
                item = self.parse(xmlelement, schema, context=context)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 32
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them"""
        result = []

        for i in max_occurs_iter(self.max_occurs):
            if xmlelements:
                xmlelement = xmlelements.pop(0)
                item = self.parse(xmlelement, schema, context=context)
                if item is not None:
                    result.append(item)
            else:
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 33
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []

        if self.accepts_multiple:
            assert name

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            item_result = OrderedDict()
            for elm_name, element in self.elements:
                try:
                    item_subresult = element.parse_xmlelements(
                        xmlelements, schema, name, context=context)
                except UnexpectedElementError:
                    if schema.settings.strict:
                        raise
                    item_subresult = None

                # Unwrap if allowed
                if isinstance(element, OrderIndicator):
                    item_result.update(item_subresult)
                else:
                    item_result[elm_name] = item_subresult

                if not xmlelements:
                    break
            if item_result:
                result.append(item_result)

        if not self.accepts_multiple:
            return result[0] if result else None
        return {name: result}
Ejemplo n.º 34
0
    def parse_kwargs(self, kwargs, name=None):
        if self.accepts_multiple:
            if name not in kwargs:
                return {}, kwargs

            item_kwargs = kwargs.pop(name)
            result = []
            sub_name = '_value_1' if self.child.accepts_multiple else None
            for i, sub_kwargs in zip(max_occurs_iter(self.max_occurs), item_kwargs):
                subresult, res_kwargs = self.child.parse_kwargs(sub_kwargs, sub_name)
                if subresult:
                    result.append(subresult)
            if result:
                result = {name: result}
        else:
            result, kwargs = self.child.parse_kwargs(kwargs, name)
        return result, kwargs
Ejemplo n.º 35
0
    def parse_kwargs(self, kwargs, name=None):
        if self.accepts_multiple:
            if name not in kwargs:
                return {}, kwargs

            item_kwargs = kwargs.pop(name)
            result = []
            sub_name = '_value_1' if self.child.accepts_multiple else None
            for i, sub_kwargs in zip(max_occurs_iter(self.max_occurs), item_kwargs):
                subresult, res_kwargs = self.child.parse_kwargs(sub_kwargs, sub_name)
                if subresult:
                    result.append(subresult)
            if result:
                result = {name: result}
        else:
            result, kwargs = self.child.parse_kwargs(kwargs, name)
        return result, kwargs
Ejemplo n.º 36
0
    def render(self, parent, value):
        """Create subelements in the given parent object."""
        if not isinstance(value, list):
            values = [value]
        else:
            values = value

        for i, value in zip(max_occurs_iter(self.max_occurs), values):
            for name, element in self.elements_nested:
                if name:
                    if name in value:
                        element_value = value[name]
                    else:
                        element_value = None
                else:
                    element_value = value
                if element_value is not None or not element.is_optional:
                    element.render(parent, element_value)
Ejemplo n.º 37
0
    def render(self, parent, value):
        if not isinstance(value, list):
            values = [value]
        else:
            values = value

        for i, value in zip(max_occurs_iter(self.max_occurs), values):
            for name, element in self.elements_nested:

                if name:
                    if isinstance(value, dict):
                        element_value = value.get(name)
                    else:
                        element_value = getattr(value, name, None)
                else:
                    element_value = value

                if element_value is not None or not element.is_optional:
                    element.render(parent, element_value)
Ejemplo n.º 38
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements and call parse() on each of them"""
        result = []
        num_matches = 0
        for i in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # Workaround for SOAP servers which incorrectly use unqualified
            # or qualified elements in the responses (#170, #176). To make the
            # best of it we compare the full uri's if both elements have a
            # namespace. If only one has a namespace then only compare the
            # localname.

            # If both elements have a namespace and they don't match then skip
            element_tag = etree.QName(xmlelements[0].tag)
            if (
                element_tag.namespace and self.qname.namespace and
                element_tag.namespace != self.qname.namespace
            ):
                break

            # Only compare the localname
            if element_tag.localname == self.qname.localname:
                xmlelement = xmlelements.popleft()
                num_matches += 1
                item = self.parse(
                    xmlelement, schema, allow_none=True, context=context)
                if item is not None:
                    result.append(item)
            else:
                # If the element passed doesn't match and the current one is
                # not optional then throw an error
                if num_matches == 0 and not self.is_optional:
                    raise UnexpectedElementError(
                        "Unexpected element %r, expected %r" % (
                            element_tag.text, self.qname.text))
                break

        if not self.accepts_multiple:
            result = result[0] if result else None
        return result
Ejemplo n.º 39
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        if self.accepts_multiple:
            if name not in kwargs:
                return {}, kwargs

            available_kwargs.remove(name)
            item_kwargs = kwargs[name]

            result = []
            sub_name = '_value_1' if self.child.accepts_multiple else None
            for i, sub_kwargs in zip(max_occurs_iter(self.max_occurs), item_kwargs):
                available_sub_kwargs = set(sub_kwargs.keys())
                subresult = self.child.parse_kwargs(
                    sub_kwargs, sub_name, available_sub_kwargs)

                if subresult:
                    result.append(subresult)
            if result:
                result = {name: result}
        else:
            result = self.child.parse_kwargs(kwargs, name, available_kwargs)
        return result
Ejemplo n.º 40
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        if self.accepts_multiple:
            if name not in kwargs:
                return {}, kwargs

            available_kwargs.remove(name)
            item_kwargs = kwargs[name]

            result = []
            sub_name = '_value_1' if self.child.accepts_multiple else None
            for i, sub_kwargs in zip(max_occurs_iter(self.max_occurs), item_kwargs):
                available_sub_kwargs = set(sub_kwargs.keys())
                subresult = self.child.parse_kwargs(
                    sub_kwargs, sub_name, available_sub_kwargs)

                if subresult:
                    result.append(subresult)
            if result:
                result = {name: result}
        else:
            result = self.child.parse_kwargs(kwargs, name, available_kwargs)
        return result
Ejemplo n.º 41
0
    def parse_xmlelements(self, xmlelements, schema, name=None, context=None):
        """Consume matching xmlelements

        :param xmlelements: Dequeue of XML element objects
        :type xmlelements: collections.deque of lxml.etree._Element
        :param schema: The parent XML schema
        :type schema: zeep.xsd.Schema
        :param name: The name of the parent element
        :type name: str
        :param context: Optional parsing context (for inline schemas)
        :type context: zeep.xsd.context.XmlParserContext
        :rtype: dict or None

        """
        result = []
        i = 1

        if self.accepts_multiple:
            assert name

        for _unused in max_occurs_iter(self.max_occurs):
            if not xmlelements:
                break

            # disgusting hack
            # for elm_name, element in self.elements:
            #
            #     if ('_value_2') == elm_name:
            #         print("====")
            #         print("====")
            #         print("====")
            #         print("====")
            #         print("====")
            #         print("====")
            #         print("======================================================LOTS OF STUFF HERE DUDE, FFFF IT UP")
            #         new_eles = []
            #         for elm_name, element in self.elements:
            #             if ('_value_1') == elm_name:
            #                 tmp = element
            #
            #             elif ('_value_2') == elm_name:
            #                 # print("OKAY BRO:\n", tmp.elements)
            #                 # for e in element.elements:
            #                 #     print("DERRR {}".format(e))
            #                 #     tmp.elements.append(e)
            #                 # print("HAHAH IT SORTA WORKED BRO:\n", tmp.elements)
            #
            #                 new_eles.append(('_value_1', tmp))
            #             else:
            #                 new_eles.append((elm_name, element))
            #
            #         self.elements = new_eles

            item_result = OrderedDict()
            for elm_name, element in self.elements:
                try:
                    item_subresult = element.parse_xmlelements(xmlelements,
                                                               schema,
                                                               name,
                                                               context=context)
                except UnexpectedElementError:
                    if schema.strict:
                        raise
                    item_subresult = None

                # Unwrap if allowed
                if isinstance(element, Choice):
                    print("PARSING RES\nres: {} \nsubres: {}".format(
                        item_result, item_subresult))
                    if '_value_1' in item_result.keys(
                    ) and '_value_1' in item_subresult.keys():
                        i += 1
                        item_subresult['_value_{}'.format(
                            i)] = item_subresult.pop('_value_1')
                        print("ALTERED? ", item_subresult)

                    item_result.update(item_subresult)
                    print("FINAL RES", item_result)
                elif isinstance(element, OrderIndicator):
                    item_result.update(item_subresult)
                else:
                    item_result[elm_name] = item_subresult

                if not xmlelements:
                    break
            if item_result:
                result.append(item_result)

        if not self.accepts_multiple:
            return result[0] if result else None
        return {name: result}
Ejemplo n.º 42
0
    def parse_kwargs(self, kwargs, name, available_kwargs):
        """Apply the given kwarg to the element.

        The available_kwargs is modified in-place. Returns a dict with the
        result.

        :param kwargs: The kwargs
        :type kwargs: dict
        :param name: The name as which this type is registered in the parent
        :type name: str
        :param available_kwargs: The kwargs keys which are still available,
         modified in place
        :type available_kwargs: set
        :rtype: dict

        """
        if self.accepts_multiple:
            assert name

        if name:
            if name not in available_kwargs:
                return {}

            assert self.accepts_multiple

            # Make sure we have a list, lame lame
            item_kwargs = kwargs.get(name)
            if not isinstance(item_kwargs, list):
                item_kwargs = [item_kwargs]

            result = []
            for item_value in max_occurs_iter(self.max_occurs, item_kwargs):
                try:
                    item_kwargs = set(item_value.keys())
                except AttributeError:
                    raise TypeError(
                        "A list of dicts is expected for unbounded Sequences")

                subresult = OrderedDict()
                for item_name, element in self.elements:
                    value = element.parse_kwargs(item_value, item_name, item_kwargs)
                    if value is not None:
                        subresult.update(value)

                if item_kwargs:
                    raise TypeError((
                        "%s() got an unexpected keyword argument %r."
                    ) % (self, list(item_kwargs)[0]))

                result.append(subresult)

            result = {name: result}

            # All items consumed
            if not any(filter(None, item_kwargs)):
                available_kwargs.remove(name)

            return result

        else:
            assert not self.accepts_multiple
            result = OrderedDict()
            for elm_name, element in self.elements_nested:
                sub_result = element.parse_kwargs(kwargs, elm_name, available_kwargs)
                if sub_result:
                    result.update(sub_result)

            return result