Changeset 470


Ignore:
Timestamp:
03/17/09 17:49:34 (5 years ago)
Author:
jortel
Message:

Fix multiref problem where references are expected to be <multiRef/> nodes. This appears to be a nameing convention used by axis (and other servers) and is not mentioned in the specification: http://www.w3.org/TR/2000/NOTE-SOAP-20000508/ section 5.1; update multiref resolver to add non (id) attributes to referencing node; update unmarshaller to ignore attributes in the soapenv ( http://www.w3.org/2003/05/soap-envelope ) namespace; update binding get_reply() methods to only raise exception for multiroot reply when root tag not mapped to message part only when node does not contain (id) attribute. This allows for sloppy multirefs

Location:
trunk/suds/bindings
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/suds/bindings/binding.py

    r469 r470  
    125125        rtypes = self.returned_types(method) 
    126126        if len(rtypes) == 1 and rtypes[0].unbounded(): 
    127             result = self.reply_list(rtypes[0], nodes) 
     127            result = self.replylist(rtypes[0], nodes) 
    128128            return (replyroot, result) 
    129129        if len(nodes) > 1: 
    130             result = self.reply_composite(rtypes, nodes) 
     130            result = self.replycomposite(rtypes, nodes) 
    131131            return (replyroot, result) 
    132132        if len(nodes) == 1: 
     
    137137        return (replyroot, None) 
    138138     
    139     def reply_list(self, rt, nodes): 
     139    def replylist(self, rt, nodes): 
    140140        """ 
    141141        Construct a I{list} reply.  This mehod is called when it has been detected 
     
    156156        return result 
    157157     
    158     def reply_composite(self, rtypes, nodes): 
     158    def replycomposite(self, rtypes, nodes): 
    159159        """ 
    160160        Construct a I{composite} reply.  This method is called when it has been 
    161         detected that the reply is a composite (object). 
    162         @param rtypes: A list of legal return I{types}. 
     161        detected that the reply has multiple root nodes. 
     162        @param rtypes: A list of known return I{types}. 
    163163        @type rtypes: [L{suds.xsd.sxbase.SchemaObject},...] 
    164164        @param nodes: A collection of XML nodes. 
     
    176176            rt = dictionary.get(tag, None) 
    177177            if rt is None: 
    178                 raise Exception('tag (%s), not-found' % tag) 
     178                if node.get('id') is None: 
     179                    raise Exception('<%s/> not mapped to message part', tag) 
     180                else: 
     181                    continue 
    179182            resolved = rt.resolve(nobuiltin=True) 
    180183            sobject = unmarshaller.process(node, resolved) 
  • trunk/suds/bindings/marshaller.py

    r463 r470  
    627627        """ 
    628628        resolved = content.type.resolve() 
    629         if ( content.type.nillable or ( resolved.builtin() and resolved.nillable ) ): 
     629        if ( content.type.nillable or \ 
     630             ( resolved.builtin() and resolved.nillable ) ): 
    630631            node.setnil() 
    631632     
  • trunk/suds/bindings/multiref.py

    r418 r470  
    2424 
    2525log = getLogger(__name__) 
     26 
     27soapenc = (None, 'http://schemas.xmlsoap.org/soap/encoding/') 
    2628 
    2729class MultiRef: 
     
    8284        ref = self.catalog.get(id) 
    8385        if ref is None: 
    84             log.error('multiRef: %s, not-resolved', id) 
     86            log.error('soap multiref: %s, not-resolved', id) 
    8587            return 
    8688        node.append(ref.children) 
    8789        node.setText(ref.getText()) 
     90        for a in ref.attributes: 
     91            if a.name != 'id': 
     92                node.append(a) 
    8893        node.remove(href) 
    8994             
     
    95100        @type body: L{Element} 
    96101        """ 
    97         for c in body.children: 
    98             if c.name == 'multiRef': 
    99                 key = '#'+c.get('id') 
    100                 self.catalog[key] = c 
    101             else: 
    102                 self.nodes.append(c) 
     102        for child in body.children: 
     103            if self.soaproot(child): 
     104                self.nodes.append(child) 
     105            id = child.get('id') 
     106            if id is None: continue 
     107            key = '#%s' % id 
     108            self.catalog[key] = child 
    103109 
     110    def soaproot(self, node): 
     111        """ 
     112        Get whether the specified I{node} is a soap encoded root. 
     113        This is determined by examining @soapenc:root='1'. 
     114        The node is considered to be a root when the attribute 
     115        is not specified. 
     116        @param node: A node to evaluate. 
     117        @type node: L{Element} 
     118        @return: True if a soap encoded root. 
     119        @rtype: bool 
     120        """ 
     121        root = node.attrib('root', ns=soapenc) 
     122        if root is None: 
     123            return True 
     124        else: 
     125            return ( root.value == '1' ) 
     126         
  • trunk/suds/bindings/unmarshaller.py

    r435 r470  
    470470        ns = attr.namespace() 
    471471        soapenc = 'http://schemas.xmlsoap.org/soap/encoding/' 
    472         skip = (Namespace.xmlns[1], soapenc) 
     472        soapenv = 'http://www.w3.org/2003/05/soap-envelope' 
     473        skip = ( 
     474            Namespace.xmlns[1], 
     475            soapenc, 
     476            soapenv 
     477        ) 
    473478        return ( Namespace.xs(ns) or ns[1] in skip ) 
Note: See TracChangeset for help on using the changeset viewer.