def parse(self, elt, ps): self.checkname(elt, ps) if self.nilled(elt, ps): return None p = self.tc.parse if self.aslist: v = [] for c in _child_elements(elt): d = p(c, ps) v.append((d['key'], d['value'])) else: v = {} for c in _child_elements(elt): d = p(c, ps) v[d['key']] = d['value'] return v
def parse(self, elt, ps): debug = self.logger.debugOn() debug and self.logger.debug('parse') xtype = self.checkname(elt, ps) if self.type and xtype not in [self.type, (None, None)]: if not isinstance(self, TypeDefinition): raise EvaluateException(\ 'ComplexType for %s has wrong type(%s), looking for %s' % (self.pname, self.checktype(elt,ps), self.type), ps.Backtrace(elt)) else: #TODO: mabye change MRO to handle this debug and self.logger.debug('delegate to substitute type') what = TypeDefinition.getSubstituteType(self, elt, ps) return what.parse(elt, ps) href = _find_href(elt) if href: if _children(elt): raise EvaluateException('Struct has content and HREF', ps.Backtrace(elt)) elt = ps.FindLocalHREF(href, elt) c = _child_elements(elt) if self.nilled(elt, ps): return Nilled # Create the object. if self.pyclass: # type definition must be informed of element tag (nspname,pname), # element declaration is initialized with a tag. try: pyobj = self.pyclass() except Exception, e: raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \ %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
def parse(self, elt, ps): debug = self.logger.debugOn() debug and self.logger.debug('parse') xtype = self.checkname(elt, ps) if self.type and xtype not in [ self.type, (None,None) ]: if not isinstance(self, TypeDefinition): raise EvaluateException(\ 'ComplexType for %s has wrong type(%s), looking for %s' % (self.pname, self.checktype(elt,ps), self.type), ps.Backtrace(elt)) else: #TODO: mabye change MRO to handle this debug and self.logger.debug('delegate to substitute type') what = TypeDefinition.getSubstituteType(self, elt, ps) return what.parse(elt, ps) href = _find_href(elt) if href: if _children(elt): raise EvaluateException('Struct has content and HREF', ps.Backtrace(elt)) elt = ps.FindLocalHREF(href, elt) c = _child_elements(elt) if self.nilled(elt, ps): return Nilled # Create the object. if self.pyclass: # type definition must be informed of element tag (nspname,pname), # element declaration is initialized with a tag. try: pyobj = self.pyclass() except Exception, e: raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \ %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
def Receive(self, replytype, **kw): '''Parse message, create Python object. KeyWord data: faults -- list of WSDL operation.fault typecodes wsaction -- If using WS-Address, must specify Action value we expect to receive. ''' self.ReceiveSOAP(**kw) ps = self.ps tp = _find_type(ps.body_root) isarray = ((type(tp) in (tuple, list) and tp[1] == 'Array') or _find_arraytype(ps.body_root)) if self.typesmodule is None or isarray: return _Binding.Receive(self, replytype, **kw) if ps.IsAFault(): msg = FaultFromFaultMessage(ps) raise FaultException(msg) tc = replytype if hasattr(replytype, 'typecode'): tc = replytype.typecode #Ignore response wrapper reply = {} for elt in _child_elements(ps.body_root): name = str(elt.localName) reply[name] = self.__parse_child(elt) if self.address is not None: self.address.checkResponse(ps, kw.get('wsaction')) return reply
def parse(self, elt, ps): href = _find_href(elt) if href: if _children(elt): raise EvaluateException('Array has content and HREF', ps.Backtrace(elt)) elt = ps.FindLocalHREF(href, elt) if self.nilled(elt, ps): return Nilled if not _find_arraytype(elt) and self.undeclared is False: raise EvaluateException('Array expected', ps.Backtrace(elt)) t = _find_type(elt) if t: pass # XXX should check the type, but parsing that is hairy. offset = self.parse_offset(elt, ps) v, vlen = [], 0 if offset and not self.sparse: while vlen < offset: vlen += 1 v.append(self.fill) for c in _child_elements(elt): item = self.ofwhat.parse(c, ps) position = self.parse_position(c, ps) or offset if self.sparse: v.append((position, item)) else: while offset < position: offset += 1 v.append(self.fill) v.append(item) offset += 1 return v
def XML(self, uri, tc, ps, **keywords): content = self.get(uri) if content: dom = ps.readerclass().fromStream(content) return _child_elements(dom)[0] if not self.next: raise EvaluateException("Unresolvable URI " + uri) return self.next.XML(uri, tc, ps, **keywords)
def XML(self, uri, tc, ps, **keywords): content = self.get(uri) if content: dom = ps.readerclass().fromStream(content) return _child_elements(dom)[0] if not self.__next__: raise EvaluateException("Unresolvable URI " + uri) return self.next.XML(uri, tc, ps, **keywords)
def Receive(self, replytype, **kw): '''Parse message, create Python object. KeyWord data: faults -- list of WSDL operation.fault typecodes wsaction -- If using WS-Address, must specify Action value we expect to receive. ''' self.ReceiveSOAP(**kw) ps = self.local.ps tp = _find_type(ps.body_root) isarray = ((isinstance(tp, _seqtypes) and tp[1] == 'Array') or _find_arraytype(ps.body_root)) if self.typesmodule is None or isarray: return _Binding.Receive(self, replytype, **kw) if ps.IsAFault(): msg = FaultFromFaultMessage(ps) raise FaultException(msg) #Ignore response wrapper reply = {} for elt in _child_elements(ps.body_root): name = str(elt.localName) reply[name] = self.__parse_child(elt) if self.address is not None: self.address.checkResponse(ps, kw.get('wsaction')) return reply
def XML(uri, tc, ps, **keywords): '''Resolve a URI and return its content as an XML DOM. ''' source = urllib.request.urlopen(uri, **keywords) enc = source.info().getencoding() if enc in ['7bit', '8bit', 'binary']: data = source else: data = StringIO.StringIO() mimetools.decode(source, data, enc) data.seek(0) dom = ps.readerclass().fromStream(data) return _child_elements(dom)[0]
def XML(uri, tc, ps, **keywords): '''Resolve a URI and return its content as an XML DOM. ''' source = urllib.urlopen(uri, **keywords) enc = source.info().getencoding() if enc in ['7bit', '8bit', 'binary']: data = source else: data = StringIO.StringIO() mimetools.decode(source, data, enc) data.seek(0) dom = ps.readerclass().fromStream(data) return _child_elements(dom)[0]
def XML(uri, tc, ps, **keywords): '''Resolve a URI and return its content as an XML DOM. ''' source = urllib.request.urlopen(uri, **keywords) enc = source.info().get('Content-Transfer-Encoding', '7bit') if enc in ['7bit', '8bit', 'binary']: data = source else: raise NotImplementedError() #data = io.StringIO() #mimetools.decode(source, data, enc) #data.seek(0) dom = ps.readerclass().fromStream(data) return _child_elements(dom)[0]
try: result = handler(arg) except Exception, ex: SendFault(FaultFromZSIException(ex), **kw) return try: tc = result.typecode except AttributeError, ex: SendFault(FaultFromZSIException(ex), **kw) return elif typesmodule is not None: kwargs = {} for e in _child_elements(ps.body_root): try: tc = gettypecode(typesmodule, e) except Exception: tc = TC.Any() try: kwargs[str(e.localName)] = tc.parse(e, ps) except EvaluateException, ex: SendFault(FaultFromZSIException(ex), **kw) return result = handler(**kwargs) aslist = False # make sure data is wrapped, try to make this a Struct if isinstance(result, _seqtypes):
def parse(self, elt, ps): debug = self.logger.debugOn() debug and self.logger.debug('parse') xtype = self.checkname(elt, ps) if self.type and xtype not in [ self.type, (None,None) ]: if not isinstance(self, TypeDefinition): raise EvaluateException(\ 'ComplexType for %s has wrong type(%s), looking for %s' % (self.pname, self.checktype(elt,ps), self.type), ps.Backtrace(elt)) else: #TODO: mabye change MRO to handle this debug and self.logger.debug('delegate to substitute type') what = TypeDefinition.getSubstituteType(self, elt, ps) return what.parse(elt, ps) href = _find_href(elt) if href: if _children(elt): raise EvaluateException('Struct has content and HREF', ps.Backtrace(elt)) elt = ps.FindLocalHREF(href, elt) c = _child_elements(elt) if self.nilled(elt, ps): return Nilled # Create the object. if self.pyclass: # type definition must be informed of element tag (nspname,pname), # element declaration is initialized with a tag. try: pyobj = self.pyclass() except Exception as e: raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \ %(self.nspname, self.pname, self.pyclass.__name__, str(e))) else: pyobj = ComplexType._DictHolder() # parse all attributes contained in attribute_typecode_dict (user-defined attributes), # the values (if not None) will be keyed in self.attributes dictionary. attributes = self.parse_attributes(elt, ps) if attributes: setattr(pyobj, self.attrs_aname, attributes) #MIXED if self.mixed is True: setattr(pyobj, self.mixed_aname, self.simple_value(elt,ps, mixed=True)) # Clone list of kids (we null it out as we process) c, crange = c[:], list(range(len(c))) # Loop over all items we're expecting for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]: for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]: # retrieve typecode if it is hidden if isinstance(what, collections.Callable): what = what() # Loop over all available kids # if debug: # self.logger.debug("what: (%s,%s)", what.nspname, what.pname) # Parse value, and mark this one done. # if debug: # self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName) match = False if what.name_match(c_elt): match = True value = what.parse(c_elt, ps) elif isinstance(what,AnyElement): match = True value = what.parse(c_elt, ps) else: # substitutionGroup head must be a global element declaration # if successful delegate to matching GED subwhat = _get_substitute_element(what, c_elt, ps) if subwhat: match = True value = subwhat.parse(c_elt, ps) if debug: self.logger.debug("substitutionGroup: %s", subwhat) if match: if what.maxOccurs > 1: attr = getattr(pyobj, what.aname, None) if attr is not None: attr.append(value) else: setattr(pyobj, what.aname, [value]) c[j] = None continue else: setattr(pyobj, what.aname, value) c[j] = None break if debug: self.logger.debug("no element (%s,%s)", what.nspname, what.pname) # No match; if it was supposed to be here, that's an error. if self.inorder is True and i == j: raise EvaluateException('Out of order complexType', ps.Backtrace(c_elt)) else: if hasattr(what, 'default'): setattr(pyobj, what.aname, what.default) # elif what.minOccurs > 0 and not hasattr(pyobj, what.aname): # raise EvaluateException('Element "' + what.aname + '" missing from complexType', ps.Backtrace(elt)) if isinstance(pyobj, ComplexType._DictHolder): return pyobj.__dict__ return pyobj
def parse(self, elt, ps): debug = self.logger.debugOn() debug and self.logger.debug('parse') xtype = self.checkname(elt, ps) if self.type and xtype not in [self.type, (None, None)]: if not isinstance(self, TypeDefinition): raise EvaluateException(\ 'ComplexType for %s has wrong type(%s), looking for %s' % (self.pname, self.checktype(elt,ps), self.type), ps.Backtrace(elt)) else: #TODO: mabye change MRO to handle this debug and self.logger.debug('delegate to substitute type') what = TypeDefinition.getSubstituteType(self, elt, ps) return what.parse(elt, ps) href = _find_href(elt) if href: if _children(elt): raise EvaluateException('Struct has content and HREF', ps.Backtrace(elt)) elt = ps.FindLocalHREF(href, elt) c = _child_elements(elt) if self.nilled(elt, ps): return Nilled # Create the object. if self.pyclass: # type definition must be informed of element tag (nspname,pname), # element declaration is initialized with a tag. try: pyobj = self.pyclass() except Exception as e: raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \ %(self.nspname, self.pname, self.pyclass.__name__, str(e))) else: pyobj = ComplexType._DictHolder() # parse all attributes contained in attribute_typecode_dict (user-defined attributes), # the values (if not None) will be keyed in self.attributes dictionary. attributes = self.parse_attributes(elt, ps) if attributes: setattr(pyobj, self.attrs_aname, attributes) #MIXED if self.mixed is True: setattr(pyobj, self.mixed_aname, self.simple_value(elt, ps, mixed=True)) # Clone list of kids (we null it out as we process) c, crange = c[:], list(range(len(c))) # Loop over all items we're expecting for j, c_elt in [(j, c[j]) for j in crange if c[j]]: for i, what in [(i, self.ofwhat[i]) for i in range(len(self.ofwhat))]: # retrieve typecode if it is hidden if isinstance(what, collections.Callable): what = what() # Loop over all available kids # if debug: # self.logger.debug("what: (%s,%s)", what.nspname, what.pname) # Parse value, and mark this one done. # if debug: # self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName) match = False if what.name_match(c_elt): match = True value = what.parse(c_elt, ps) elif isinstance(what, AnyElement): match = True value = what.parse(c_elt, ps) else: # substitutionGroup head must be a global element declaration # if successful delegate to matching GED subwhat = _get_substitute_element(what, c_elt, ps) if subwhat: match = True value = subwhat.parse(c_elt, ps) if debug: self.logger.debug("substitutionGroup: %s", subwhat) if match: if what.maxOccurs > 1: attr = getattr(pyobj, what.aname, None) if attr is not None: attr.append(value) else: setattr(pyobj, what.aname, [value]) c[j] = None continue else: setattr(pyobj, what.aname, value) c[j] = None break if debug: self.logger.debug("no element (%s,%s)", what.nspname, what.pname) # No match; if it was supposed to be here, that's an error. if self.inorder is True and i == j: raise EvaluateException('Out of order complexType', ps.Backtrace(c_elt)) else: if hasattr(what, 'default'): setattr(pyobj, what.aname, what.default) # elif what.minOccurs > 0 and not hasattr(pyobj, what.aname): # raise EvaluateException('Element "' + what.aname + '" missing from complexType', ps.Backtrace(elt)) if isinstance(pyobj, ComplexType._DictHolder): return pyobj.__dict__ return pyobj
def __init__(self, input, readerclass=None, keepdom=False, trailers=False, resolver=None, envelope=True, **kw): '''Initialize. Keyword arguments: trailers -- allow trailer elments (default is zero) resolver -- function (bound method) to resolve URI's readerclass -- factory class to create a reader keepdom -- do not release the DOM envelope -- look for a SOAP envelope. ''' self.readerclass = readerclass self.keepdom = keepdom if not self.readerclass: self.readerclass = self.defaultReaderClass try: self.reader = self.readerclass() if isinstance(input, str): self.dom = self.reader.fromString(input) elif isinstance(input, bytes): self.dom = self.reader.fromString(input.decode(UNICODE_ENCODING)) else: self.dom = self.reader.fromStream(input) except Exception as e: # Is this in the header? Your guess is as good as mine. #raise ParseException("Can't parse document (" + \ # str(e.__class__) + "): " + str(e), 0) raise self.ns_cache = { id(self.dom): { 'xml': XMLNS.XML, 'xmlns': XMLNS.BASE, '': '' } } self.trailers, self.resolver, self.id_cache = trailers, resolver, {} # Exactly one child element c = [ E for E in _children(self.dom) if E.nodeType == _Node.ELEMENT_NODE] if len(c) == 0: raise ParseException("Document has no Envelope", 0) if len(c) != 1: raise ParseException("Document has extra child elements", 0) if envelope is False: self.body_root = c[0] return # And that one child must be the Envelope elt = c[0] if elt.localName != "Envelope" \ or elt.namespaceURI != SOAP.ENV: raise ParseException('Document has "' + elt.localName + \ '" element, not Envelope', 0) self._check_for_legal_children("Envelope", elt) for a in _attrs(elt): name = a.nodeName if name.find(":") == -1 and name not in [ "xmlns", "id" ]: raise ParseException('Unqualified attribute "' + \ name + '" in Envelope', 0) self.envelope = elt if not _valid_encoding(self.envelope): raise ParseException("Envelope has invalid encoding", 0) # Get Envelope's child elements. c = [ E for E in _children(self.envelope) if E.nodeType == _Node.ELEMENT_NODE ] if len(c) == 0: raise ParseException("Envelope is empty (no Body)", 0) # Envelope's first child might be the header; if so, nip it off. elt = c[0] if elt.localName == "Header" \ and elt.namespaceURI == SOAP.ENV: self._check_for_legal_children("Header", elt) self._check_for_pi_nodes(_children(elt), 1) self.header = c.pop(0) self.header_elements = _child_elements(self.header) else: self.header, self.header_elements = None, [] # Now the first child must be the body if len(c) == 0: raise ParseException("Envelope has header but no Body", 0) elt = c.pop(0) if elt.localName != "Body" \ or elt.namespaceURI != SOAP.ENV: if self.header: raise ParseException('Header followed by "' + \ elt.localName + \ '" element, not Body', 0, elt, self.dom) else: raise ParseException('Document has "' + \ elt.localName + \ '" element, not Body', 0, elt, self.dom) self._check_for_legal_children("Body", elt, 0) self._check_for_pi_nodes(_children(elt), 0) self.body = elt if not _valid_encoding(self.body): raise ParseException("Body has invalid encoding", 0) # Trailer elements. if not self.trailers: if len(c): raise ParseException("Element found after Body", 0, elt, self.dom) # Don't set self.trailer_elements = []; if user didn't ask # for trailers we *want* to throw an exception. else: self.trailer_elements = c for elt in self.trailer_elements: if not elt.namespaceURI: raise ParseException('Unqualified trailer element', 0, elt, self.dom) # Find the serialization root. Divide the Body children into # root (root=1), no (root=0), maybe (no root attribute). self.body_root, no, maybe = None, [], [] for elt in _child_elements(self.body): root = _find_root(elt) if root == "1": if self.body_root: raise ParseException("Multiple seralization roots found", 0, elt, self.dom) self.body_root = elt elif root == "0": no.append(elt) elif not root: maybe.append(elt) else: raise ParseException('Illegal value for root attribute', 0, elt, self.dom) # If we didn't find a root, get the first one that didn't # say "not me", unless they all said "not me." if self.body_root is None: if len(maybe): self.body_root = maybe[0] else: raise ParseException('No serialization root found', 0, self.body, self.dom) if not _valid_encoding(self.body_root): raise ParseException("Invalid encoding", 0, elt, self.dom) # Now get all the non-roots (in order!). rootid = id(self.body_root) self.data_elements = [ E for E in _child_elements(self.body) if id(E) != rootid ] self._check_for_pi_nodes(self.data_elements, 0)
def parse(self, elt, ps): debug = self.logger.debugOn() debug and self.logger.debug('parse') xtype = self.checkname(elt, ps) if self.type and xtype not in [ self.type, (None,None) ]: if not isinstance(self, TypeDefinition): raise EvaluateException(\ 'ComplexType for %s has wrong type(%s), looking for %s' % (self.pname, self.checktype(elt,ps), self.type), ps.Backtrace(elt)) else: #TODO: mabye change MRO to handle this debug and self.logger.debug('delegate to substitute type') what = TypeDefinition.getSubstituteType(self, elt, ps) return what.parse(elt, ps) href = _find_href(elt) if href: if _children(elt): raise EvaluateException('Struct has content and HREF', ps.Backtrace(elt)) elt = ps.FindLocalHREF(href, elt) c = _child_elements(elt) count = len(c) if self.nilled(elt, ps): return Nilled # Create the object. v = {} # parse all attributes contained in attribute_typecode_dict (user-defined attributes), # the values (if not None) will be keyed in self.attributes dictionary. attributes = self.parse_attributes(elt, ps) if attributes: v[self.attrs_aname] = attributes #MIXED if self.mixed is True: v[self.mixed_aname] = self.simple_value(elt,ps, mixed=True) # Clone list of kids (we null it out as we process) c, crange = c[:], list(range(len(c))) # Loop over all items we're expecting if debug: self.logger.debug("ofwhat: %s",str(self.ofwhat)) any = None for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]: # retrieve typecode if it is hidden if isinstance(what, collections.Callable): what = what() # Loop over all available kids if debug: self.logger.debug("what: (%s,%s)", what.nspname, what.pname) for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]: # Parse value, and mark this one done. if debug: self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, c_elt.tagName) match = False if what.name_match(c_elt): match = True value = what.parse(c_elt, ps) else: # substitutionGroup head must be a global element declaration # if successful delegate to matching GED subwhat = _get_substitute_element(what, c_elt, ps) if subwhat: match = True value = subwhat.parse(c_elt, ps) if debug: self.logger.debug("substitutionGroup: %s", subwhat) if match: if what.maxOccurs == UNBOUNDED or what.maxOccurs > 1: if what.aname in v: v[what.aname].append(value) else: v[what.aname] = [value] c[j] = None continue else: v[what.aname] = value c[j] = None break if debug: self.logger.debug("no element (%s,%s)", what.nspname, what.pname) # No match; if it was supposed to be here, that's an error. if self.inorder is True and i == j: raise EvaluateException('Out of order complexType', ps.Backtrace(c_elt)) else: # only supporting 1 <any> declaration in content. if isinstance(what,AnyElement): any = what elif hasattr(what, 'default'): v[what.aname] = what.default elif what.minOccurs > 0 and what.aname not in v: raise EvaluateException('Element "' + what.aname + \ '" missing from complexType', ps.Backtrace(elt)) # Look for wildcards and unprocessed children # XXX Stick all this stuff in "any", hope for no collisions if any is not None: occurs = 0 v[any.aname] = [] for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]: value = any.parse(c_elt, ps) if any.maxOccurs == UNBOUNDED or any.maxOccurs > 1: v[any.aname].append(value) else: v[any.aname] = value occurs += 1 # No such thing as nillable <any> if any.maxOccurs == 1 and occurs == 0: v[any.aname] = None elif occurs < any.minOccurs or (any.maxOccurs!=UNBOUNDED and any.maxOccurs<occurs): raise EvaluateException('occurances of <any> elements(#%d) bound by (%d,%s)' %( occurs, any.minOccurs,str(any.maxOccurs)), ps.Backtrace(elt)) if not self.pyclass: return v # type definition must be informed of element tag (nspname,pname), # element declaration is initialized with a tag. try: pyobj = self.pyclass() except Exception as e: raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \ %(self.nspname, self.pname, self.pyclass.__name__, str(e))) for key in list(v.keys()): setattr(pyobj, key, v[key]) return pyobj
def __init__(self, _input, readerclass=None, keepdom=False, trailers=False, resolver=None, envelope=True, **kw): """Initialize. Keyword arguments: trailers -- allow trailer elments (default is zero) resolver -- function (bound method) to resolve URI's readerclass -- factory class to create a reader keepdom -- do not release the DOM envelope -- look for a SOAP envelope. """ self.readerclass = readerclass self.keepdom = keepdom if not self.readerclass: self.readerclass = self.defaultReaderClass try: self.reader = self.readerclass() if isinstance(_input, _stringtypes): self.dom = self.reader.fromString(_input) else: self.dom = self.reader.fromStream(_input) except Exception: # Is this in the header? Your guess is as good as mine. #raise ParseException("Can't parse document (" + \ # str(e.__class__) + "): " + str(e), 0) raise self.ns_cache = { id(self.dom): { 'xml': XMLNS.XML, 'xmlns': XMLNS.BASE, '': '' } } self.trailers, self.resolver, self.id_cache = trailers, resolver, {} # Exactly one child element c = [ E for E in _children(self.dom) if E.nodeType == _Node.ELEMENT_NODE] if len(c) == 0: raise ParseException("Document has no Envelope", 0) if len(c) != 1: raise ParseException("Document has extra child elements", 0) if envelope is False: self.body_root = c[0] return # And that one child must be the Envelope elt = c[0] if elt.localName != "Envelope" \ or elt.namespaceURI != SOAP.ENV: raise ParseException('Document has "' + elt.localName + \ '" element, not Envelope', 0) self._check_for_legal_children("Envelope", elt) for a in _attrs(elt): name = a.nodeName if name.find(":") == -1 and name not in [ "xmlns", "id" ]: raise ParseException('Unqualified attribute "' + \ name + '" in Envelope', 0) self.envelope = elt if not _valid_encoding(self.envelope): raise ParseException("Envelope has invalid encoding", 0) # Get Envelope's child elements. c = [ E for E in _children(self.envelope) if E.nodeType == _Node.ELEMENT_NODE ] if len(c) == 0: raise ParseException("Envelope is empty (no Body)", 0) # Envelope's first child might be the header; if so, nip it off. elt = c[0] if elt.localName == "Header" \ and elt.namespaceURI == SOAP.ENV: self._check_for_legal_children("Header", elt) self._check_for_pi_nodes(_children(elt), 1) self.header = c.pop(0) self.header_elements = _child_elements(self.header) else: self.header, self.header_elements = None, [] # Now the first child must be the body if len(c) == 0: raise ParseException("Envelope has header but no Body", 0) elt = c.pop(0) if elt.localName != "Body" \ or elt.namespaceURI != SOAP.ENV: if self.header: raise ParseException('Header followed by "' + \ elt.localName + \ '" element, not Body', 0, elt, self.dom) else: raise ParseException('Document has "' + \ elt.localName + \ '" element, not Body', 0, elt, self.dom) self._check_for_legal_children("Body", elt, 0) self._check_for_pi_nodes(_children(elt), 0) self.body = elt if not _valid_encoding(self.body): raise ParseException("Body has invalid encoding", 0) # Trailer elements. if not self.trailers: if len(c): raise ParseException("Element found after Body", 0, elt, self.dom) # Don't set self.trailer_elements = []; if user didn't ask # for trailers we *want* to throw an exception. else: self.trailer_elements = c for elt in self.trailer_elements: if not elt.namespaceURI: raise ParseException('Unqualified trailer element', 0, elt, self.dom) # Find the serialization root. Divide the Body children into # root (root=1), no (root=0), maybe (no root attribute). self.body_root, no, maybe = None, [], [] for elt in _child_elements(self.body): root = _find_root(elt) if root == "1": if self.body_root: raise ParseException("Multiple seralization roots found", 0, elt, self.dom) self.body_root = elt elif root == "0": no.append(elt) elif not root: maybe.append(elt) else: raise ParseException('Illegal value for root attribute', 0, elt, self.dom) # If we didn't find a root, get the first one that didn't # say "not me", unless they all said "not me." if self.body_root is None: if len(maybe): self.body_root = maybe[0] else: raise ParseException('No serialization root found', 0, self.body, self.dom) if not _valid_encoding(self.body_root): raise ParseException("Invalid encoding", 0, elt, self.dom) # Now get all the non-roots (in order!). rootid = id(self.body_root) self.data_elements = [ E for E in _child_elements(self.body) if id(E) != rootid ] self._check_for_pi_nodes(self.data_elements, 0)
def _Dispatch(ps, modules, SendResponse, SendFault, nsdict={}, typesmodule=None, gettypecode=gettypecode, rpc=False, docstyle=False, **kw): '''Find a handler for the SOAP request in ps; search modules. Call SendResponse or SendFault to send the reply back, appropriately. Behaviors: default -- Call "handler" method with pyobj representation of body root, and return a self-describing request (w/typecode). Parsing done via a typecode from typesmodule, or Any. docstyle -- Call "handler" method with ParsedSoap instance and parse result with an XML typecode (DOM). Behavior, wrap result in a body_root "Response" appended message. rpc -- Specify RPC wrapper of result. Behavior, ignore body root (RPC Wrapper) of request, parse all "parts" of message via individual typecodes. Expect the handler to return the parts of the message, whether it is a dict, single instance, or a list try to serialize it as a Struct but if this is not possible put it in an Array. Parsing done via a typecode from typesmodule, or Any. ''' global _client_binding try: what = str(ps.body_root.localName) # See what modules have the element name. if modules is None: modules = (sys.modules['__main__'], ) handlers = [getattr(m, what) for m in modules if hasattr(m, what)] if len(handlers) == 0: raise TypeError("Unknown method " + what) # Of those modules, see who's callable. handlers = [h for h in handlers if isinstance(h, collections.Callable)] if len(handlers) == 0: raise TypeError("Unimplemented method " + what) if len(handlers) > 1: raise TypeError("Multiple implementations found: " + repr(handlers)) handler = handlers[0] _client_binding = ClientBinding(ps) if docstyle: result = handler(ps.body_root) tc = TC.XML(aslist=1, pname=what + 'Response') elif not rpc: try: tc = gettypecode(typesmodule, ps.body_root) except Exception: tc = TC.Any() try: arg = tc.parse(ps.body_root, ps) except EvaluateException as ex: SendFault(FaultFromZSIException(ex), **kw) return try: result = handler(arg) except Exception as ex: SendFault(FaultFromZSIException(ex), **kw) return try: tc = result.typecode except AttributeError as ex: SendFault(FaultFromZSIException(ex), **kw) return elif typesmodule is not None: kwargs = {} for e in _child_elements(ps.body_root): try: tc = gettypecode(typesmodule, e) except Exception: tc = TC.Any() try: kwargs[str(e.localName)] = tc.parse(e, ps) except EvaluateException as ex: SendFault(FaultFromZSIException(ex), **kw) return result = handler(**kwargs) aslist = False # make sure data is wrapped, try to make this a Struct if type(result) in _seqtypes: for o in result: aslist = hasattr(result, 'typecode') if aslist: break elif type(result) is not dict: aslist = not hasattr(result, 'typecode') result = (result, ) tc = TC.Any(pname=what + 'Response', aslist=aslist) else: # if this is an Array, call handler with list # if this is an Struct, call handler with dict tp = _find_type(ps.body_root) isarray = ((type(tp) in (tuple, list) and tp[1] == 'Array') or _find_arraytype(ps.body_root)) data = _child_elements(ps.body_root) tc = TC.Any() if isarray and len(data) == 0: result = handler() elif isarray: try: arg = [tc.parse(e, ps) for e in data] except EvaluateException as e: #SendFault(FaultFromZSIException(e), **kw) SendFault(RuntimeError("THIS IS AN ARRAY: %s" % isarray)) return result = handler(*arg) else: try: kwarg = dict([(str(e.localName), tc.parse(e, ps)) for e in data]) except EvaluateException as e: SendFault(FaultFromZSIException(e), **kw) return result = handler(**kwarg) # reponse typecode #tc = getattr(result, 'typecode', TC.Any(pname=what+'Response')) tc = TC.Any(pname=what + 'Response') sw = SoapWriter(nsdict=nsdict) sw.serialize(result, tc) return SendResponse(str(sw), **kw) except Fault as e: return SendFault(e, **kw) except Exception as e: # Something went wrong, send a fault. return SendFault(FaultFromException(e, 0, sys.exc_info()[2]), **kw)
try: result = handler(arg) except Exception,ex: SendFault(FaultFromZSIException(ex), **kw) return try: tc = result.typecode except AttributeError,ex: SendFault(FaultFromZSIException(ex), **kw) return elif typesmodule is not None: kwargs = {} for e in _child_elements(ps.body_root): try: tc = gettypecode(typesmodule, e) except Exception: tc = TC.Any() try: kwargs[str(e.localName)] = tc.parse(e, ps) except EvaluateException, ex: SendFault(FaultFromZSIException(ex), **kw) return result = handler(**kwargs) aslist = False # make sure data is wrapped, try to make this a Struct if isinstance(result,_seqtypes):