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
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}
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)
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
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
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}
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)
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}
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}
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
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
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
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
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}
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}
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
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
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
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
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
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
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
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
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}
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
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
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}
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
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)
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)
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
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
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}
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