def create_xml_soap_map(values): """Create an http://xml.apache.org/xml-soap#Map value.""" Map = xsd.ComplexType( xsd.Sequence([ xsd.Element("item", xsd.AnyType(), min_occurs=1, max_occurs="unbounded") ]), qname=etree.QName("{http://xml.apache.org/xml-soap}Map"), ) KeyValueData = xsd.Element( "{http://xml.apache.org/xml-soap}KeyValueData", xsd.ComplexType( xsd.Sequence([ xsd.Element("key", xsd.AnyType()), xsd.Element("value", xsd.AnyType()) ])), ) return Map(item=[ KeyValueData( xsd.AnyObject(xsd.String(), key), xsd.AnyObject(guess_xsd_type(value), value), ) for key, value in values.items() ])
def _resolve_body(self, info, definitions, parts): """Return an XSD element for the SOAP:Body. Each part is a parameter or a return value and appears inside a wrapper element within the body named identically to the operation name and its namespace is the value of the namespace attribute. """ if not info: return None namespace = info["namespace"] if self.type == "input": tag_name = etree.QName(namespace, self.operation.name) else: tag_name = etree.QName(namespace, self.abstract.name.localname) # Create the xsd element to create/parse the response. Each part # is a sub element of the root node (which uses the operation name) elements = [] for name, msg in parts.items(): if msg.element: elements.append(msg.element) else: elements.append(xsd.Element(name, msg.type)) return xsd.Element(tag_name, xsd.ComplexType(xsd.Sequence(elements)))
def resolve(self, definitions, abstract_message): """Resolve the body element The specs are (again) not really clear how to handle the message parts in relation the message element vs type. The following strategy is chosen, which seem to work: - If the message part has a name and it maches then set it as body - If the message part has a name but it doesn't match but there are no other message parts, then just use that one. - If the message part has no name then handle it like an rpc call, in other words, each part is an argument. """ self.abstract = abstract_message if self.part_name and self.abstract.parts: if self.part_name in self.abstract.parts: message = self.abstract.parts[self.part_name] elif len(self.abstract.parts) == 1: message = list(self.abstract.parts.values())[0] else: raise ValueError( "Multiple parts for message %r while no matching part found" % self.part_name) if message.element: self.body = message.element else: elm = xsd.Element(self.part_name, message.type) self.body = xsd.Element(self.operation.name, xsd.ComplexType(xsd.Sequence([elm]))) else: children = [] for name, message in self.abstract.parts.items(): if message.element: elm = message.element.clone(name) else: elm = xsd.Element(name, message.type) children.append(elm) self.body = xsd.Element(self.operation.name, xsd.ComplexType(xsd.Sequence(children)))
def resolve(self, definitions, abstract_message): self.abstract = abstract_message children = [] for name, message in self.abstract.parts.items(): if message.element: elm = message.element.clone(name) else: elm = xsd.Element(name, message.type) children.append(elm) self.body = xsd.Element( self.operation.name, xsd.ComplexType(xsd.Sequence(children)) )
def _create_envelope_element(self): """Create combined `envelope` complexType which contains both the elements from the body and the headers. """ all_elements = xsd.Sequence([]) if self.header.type._element: all_elements.append( xsd.Element("{%s}header" % self.nsmap["soap-env"], self.header.type)) all_elements.append( xsd.Element( "{%s}body" % self.nsmap["soap-env"], self.body.type if self.body else None, )) return xsd.Element("{%s}envelope" % self.nsmap["soap-env"], xsd.ComplexType(all_elements))