Ejemplo n.º 1
0
 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 None
     if not _find_arraytype(elt) and not self.undeclared:
         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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
 def FindLocalHREF(self, href, elt, headers=1):
     """Find a local HREF in the data elements.
     """
     if href[0] != "#":
         raise EvaluateException('Absolute HREF ("%s") not implemented' % href, self.Backtrace(elt))
     frag = href[1:]
     # Already found?
     e = self.id_cache.get(frag)
     if e:
         return e
     # Do a breadth-first search, in the data first.  Most likely
     # to find multi-ref targets shallow in the data area.
     list = self.data_elements[:] + [self.body_root]
     if headers:
         list.extend(self.header_elements)
     while list:
         e = list.pop()
         if e.nodeType == _Node.ELEMENT_NODE:
             nodeid = _find_id(e)
             if nodeid:
                 self.id_cache[nodeid] = e
                 if nodeid == frag:
                     return e
         list += _children(e)
     raise EvaluateException('''Can't find node for HREF "%s"''' % href, self.Backtrace(elt))
Ejemplo n.º 4
0
 def parse(self, elt, ps):
     (ns,type) = self.checkname(elt, ps)
     if not type and self.nilled(elt, ps): return None
     if len(_children(elt)) == 0:
         href = _find_href(elt)
         if not href:
             if self.optional: return None
             raise EvaluateException('Non-optional Any missing',
                     ps.Backtrace(elt))
         elt = ps.FindLocalHREF(href, elt)
         (ns,type) = self.checktype(elt, ps)
     if not type and elt.namespaceURI == SOAP.ENC:
         ns,type = SOAP.ENC, elt.localName
     if not type or (ns,type) == (SOAP.ENC,'Array'):
         if self.aslist or _find_arraytype(elt):
             return [ Any(aslist=self.aslist).parse(e, ps)
                         for e in _child_elements(elt) ]
         if len(_child_elements(elt)) == 0:
             raise EvaluateException("Any cannot parse untyped element",
                     ps.Backtrace(elt))
         return self.parse_into_dict_or_list(elt, ps)
     parser = Any.parsemap.get((ns,type))
     if not parser and _is_xsd_or_soap_ns(ns):
         parser = Any.parsemap.get((None,type))
     if not parser:
         raise EvaluateException('''Any can't parse element''',
                 ps.Backtrace(elt))
     return parser.parse(elt, ps)
Ejemplo n.º 5
0
 def FindLocalHREF(self, href, elt, headers=1):
     '''Find a local HREF in the data elements.
     '''
     if href[0] != '#':
         raise EvaluateException(
             'Absolute HREF ("%s") not implemented' % href,
             self.Backtrace(elt))
     frag = href[1:]
     # Already found?
     e = self.id_cache.get(frag)
     if e: return e
     # Do a breadth-first search, in the data first.  Most likely
     # to find multi-ref targets shallow in the data area.
     list = self.data_elements[:] + [self.body_root]
     if headers: list.extend(self.header_elements)
     while list:
         e = list.pop()
         if e.nodeType == _Node.ELEMENT_NODE:
             nodeid = _find_id(e)
             if nodeid:
                 self.id_cache[nodeid] = e
                 if nodeid == frag: return e
         list += _children(e)
     raise EvaluateException('''Can't find node for HREF "%s"''' % href,
                             self.Backtrace(elt))
Ejemplo n.º 6
0
 def SimpleHREF(self, elt, ps, tag):
     '''Simple HREF for non-string and non-struct and non-array.
     '''
     if len(_children(elt)): return elt
     href = _find_href(elt)
     if not href:
         if self.optional: return None
         raise EvaluateException('Non-optional ' + tag + ' missing',
                 ps.Backtrace(elt))
     return ps.FindLocalHREF(href, elt, 0)
Ejemplo n.º 7
0
 def parse(self, elt, ps):
     self.checkname(elt, ps)
     if len(_children(elt)) == 0:
         href = _find_href(elt)
         if not href:
             if _find_nil(elt) not in [ "true",  "1"]:
                 # No content, no HREF, not NIL:  empty string
                 return ""
             # No content, no HREF, and is NIL...
             if self.optional: return None
             raise EvaluateException('Non-optional string missing',
                     ps.Backtrace(elt))
         if href[0] != '#':
             return ps.ResolveHREF(href, self)
         elt = ps.FindLocalHREF(href, elt)
         self.checktype(elt, ps)
     if self.nilled(elt, ps): return None
     if len(_children(elt)) == 0: return ''
     v = self.simple_value(elt, ps)
     if self.strip: v = v.strip()
     return v
Ejemplo n.º 8
0
 def _check_for_pi_nodes(self, list, inheader):
     """Raise an exception if any of the list descendants are PI nodes.
     """
     list = list[:]
     while list:
         elt = list.pop()
         t = elt.nodeType
         if t == _Node.PROCESSING_INSTRUCTION_NODE:
             raise ParseException(
                 'Found processing instruction "<?' + elt.nodeName + '...>"', inheader, elt.parentNode, self.dom
             )
         elif t == _Node.DOCUMENT_TYPE_NODE:
             raise ParseException("Found DTD", inheader, elt.parentNode, self.dom)
         list += _children(elt)
Ejemplo n.º 9
0
def FaultFromFaultMessage(ps):
    '''Parse the message as a fault.
    '''
    d = { 'faultcode': None, 'faultstring': None, 'faultactor': None,
        'detail': None, }
    for elt in _child_elements(ps.body_root):
        n = elt.localName
        if n == 'detail':
            d['detail'] = _child_elements(elt)
        if n in [ 'faultcode', 'faultstring', 'faultactor' ]:
            d[n] = ''.join([E.nodeValue for E in _children(elt)
                            if E.nodeType 
                            in [ _Node.TEXT_NODE, _Node.CDATA_SECTION_NODE ]])
    return Fault(d['faultcode'], d['faultstring'],
                d['faultactor'], d['detail'])
Ejemplo n.º 10
0
 def _check_for_pi_nodes(self, list, inheader):
     '''Raise an exception if any of the list descendants are PI nodes.
     '''
     list = list[:]
     while list:
         elt = list.pop()
         t = elt.nodeType
         if t == _Node.PROCESSING_INSTRUCTION_NODE:
             raise ParseException('Found processing instruction "<?' + \
                     elt.nodeName + '...>"',
                     inheader, elt.parentNode, self.dom)
         elif t == _Node.DOCUMENT_TYPE_NODE:
             raise ParseException('Found DTD', inheader, elt.parentNode,
                                  self.dom)
         list += _children(elt)
Ejemplo n.º 11
0
 def _check_for_legal_children(self, name, elt, mustqualify=1):
     """Check if all children of this node are elements or whitespace-only
     text nodes.
     """
     inheader = name == "Header"
     for n in _children(elt):
         t = n.nodeType
         if t == _Node.COMMENT_NODE:
             continue
         if t != _Node.ELEMENT_NODE:
             if t == _Node.TEXT_NODE and n.nodeValue.strip() == "":
                 continue
             raise ParseException("Non-element child in " + name, inheader, elt, self.dom)
         if mustqualify and not n.namespaceURI:
             raise ParseException('Unqualified element "' + n.nodeName + '" in ' + name, inheader, elt, self.dom)
Ejemplo n.º 12
0
 def _check_for_legal_children(self, name, elt, mustqualify=1):
     '''Check if all children of this node are elements or whitespace-only
     text nodes.
     '''
     inheader = name == "Header"
     for n in _children(elt):
         t = n.nodeType
         if t == _Node.COMMENT_NODE: continue
         if t != _Node.ELEMENT_NODE:
             if t == _Node.TEXT_NODE and n.nodeValue.strip() == "":
                 continue
             raise ParseException("Non-element child in " + name, inheader,
                                  elt, self.dom)
         if mustqualify and not n.namespaceURI:
             raise ParseException('Unqualified element "' + \
                     n.nodeName + '" in ' + name, inheader, elt, self.dom)
Ejemplo n.º 13
0
    def simple_value(self, elt, ps):
        '''Get the value of the simple content of this element.
        '''
        if not _valid_encoding(elt):
            raise EvaluateException('Invalid encoding', ps.Backtrace(elt))
        c = _children(elt)
        if len(c) == 0:
            raise EvaluateException('Value missing', ps.Backtrace(elt))
        for c_elt in c:
            if c_elt.nodeType == _Node.ELEMENT_NODE:
                raise EvaluateException('Sub-elements in value',
                    ps.Backtrace(c_elt))

        # It *seems* to be consensus that ignoring comments and
        # concatenating the text nodes is the right thing to do.
        return ''.join([E.nodeValue for E in c
                if E.nodeType 
                in [ _Node.TEXT_NODE, _Node.CDATA_SECTION_NODE ]])
Ejemplo n.º 14
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.
        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)))
Ejemplo n.º 15
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.
        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)))
Ejemplo n.º 16
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[:], 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 callable(what): 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 > 1:
                        if v.has_key(what.aname):
                            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 not v.has_key(what.aname):
                    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, e:
            raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
Ejemplo n.º 17
0
 def parse(self, elt, ps):
     self.checkname(elt, ps)
     if len(_children(elt)):
         raise EvaluateException('Void got a value', ps.Backtrace(elt))
     return None
Ejemplo n.º 18
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[:], 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 callable(what): 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 > 1:
                        if v.has_key(what.aname):
                            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 not v.has_key(what.aname):
                    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, e:
            raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
                %(self.nspname, self.pname, self.pyclass.__name__, str(e)))
Ejemplo n.º 19
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[:], 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 callable(what): 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] ]:
                if debug:
                    self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, 
                                      c_elt.tagName)
                if what.name_match(c_elt):
                    # Parse value, and mark this one done. 
                    try:
                        value = what.parse(c_elt, ps)
                    except EvaluateException, e:
                        #what = _get_substitute_element(c_elt, what)
                        #value = what.parse(c_elt, ps)
                        raise
                    if what.maxOccurs > 1:
                        if v.has_key(what.aname):
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break
                else:
                    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 not v.has_key(what.aname):
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from complexType', ps.Backtrace(elt))
Ejemplo n.º 20
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[:], 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 callable(what): 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] ]:
                if debug:
                    self.logger.debug("child node: (%s,%s)", c_elt.namespaceURI, 
                                      c_elt.tagName)
                if what.name_match(c_elt):
                    # Parse value, and mark this one done. 
                    try:
                        value = what.parse(c_elt, ps)
                    except EvaluateException, e:
                        #what = _get_substitute_element(c_elt, what)
                        #value = what.parse(c_elt, ps)
                        raise
                    if what.maxOccurs > 1:
                        if v.has_key(what.aname):
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break
                else:
                    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 not v.has_key(what.aname):
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from complexType', ps.Backtrace(elt))
Ejemplo n.º 21
0
    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:
            if self.defaultReaderClass != None:
                self.readerclass = self.defaultReaderClass
            else:
                from xml.dom.ext.reader import PyExpat

                self.readerclass = PyExpat.Reader
        try:
            self.reader = self.readerclass()
            if type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            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)
Ejemplo n.º 22
0
class ParsedSoap:
    '''A Parsed SOAP object.
        Convert the text to a DOM tree and parse SOAP elements.
        Instance data:
            reader -- the DOM reader
            dom -- the DOM object
            ns_cache -- dictionary (by id(node)) of namespace dictionaries
            id_cache -- dictionary (by XML ID attr) of elements
            envelope -- the node holding the SOAP Envelope
            header -- the node holding the SOAP Header (or None)
            body -- the node holding the SOAP Body
            body_root -- the serialization root in the SOAP Body
            data_elements -- list of non-root elements in the SOAP Body
            trailer_elements -- list of elements following the SOAP body
    '''
    defaultReaderClass = DefaultReader

    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 type(input) in _stringtypes:
                self.dom = self.reader.fromString(input)
            else:
                self.dom = self.reader.fromStream(input)
        except Exception, 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)
Ejemplo n.º 23
0
    def _do_element(self, node, initial_other_attrs = []):
        '''_do_element(self, node, initial_other_attrs = []) -> None
        Process an element (and its children).'''

        # Get state (from the stack) make local copies.
        #       ns_parent -- NS declarations in parent
        #       ns_rendered -- NS nodes rendered by ancestors
        #       xml_attrs -- Attributes in XML namespace from parent
        #       ns_local -- NS declarations relevant to this element
        ns_parent, ns_rendered, xml_attrs = \
                self.state[0], self.state[1][:], self.state[2][:]
        ns_local = ns_parent.copy()

        # Divide attributes into NS, XML, and others.
        other_attrs = initial_other_attrs[:]
        in_subset = _in_subset(self.subset, node)
        for a in _attrs(node):
            if a.namespaceURI == XMLNS.BASE:
                n = a.nodeName
                if n == "xmlns:": n = "xmlns"        # DOM bug workaround
                ns_local[n] = a.nodeValue
            elif a.namespaceURI == XMLNS.XML:
                if self.unsuppressedPrefixes is None or in_subset:
                    xml_attrs.append(a)
            else:
                other_attrs.append(a)

        # Render the node
        W, name = self.write, None
        if in_subset:
            name = node.nodeName
            W('<')
            W(name)

            # Create list of NS attributes to render.
            ns_to_render = []
            for n,v in ns_local.items():
                pval = ns_parent.get(n)

                # If default namespace is XMLNS.BASE or empty, skip
                if n == "xmlns" \
                and v in [ XMLNS.BASE, '' ] and pval in [ XMLNS.BASE, '' ]:
                    continue

                # "omit namespace node with local name xml, which defines
                # the xml prefix, if its string value is
                # http://www.w3.org/XML/1998/namespace."
                if n == "xmlns:xml" \
                and v in [ 'http://www.w3.org/XML/1998/namespace' ]:
                    continue

                # If different from parent, or parent didn't render
                # and if not exclusive, or this prefix is needed or
                # not suppressed
                if (v != pval or n not in ns_rendered) \
                  and (self.unsuppressedPrefixes is None or \
                  _utilized(n, node, other_attrs, self.unsuppressedPrefixes)):
                    ns_to_render.append((n, v))

            # Sort and render the ns, marking what was rendered.
            ns_to_render.sort(_sorter_ns)
            for n,v in ns_to_render:
                self._do_attr(n, v)
                ns_rendered.append(n)

            # Add in the XML attributes (don't pass to children, since
            # we're rendering them), sort, and render.
            other_attrs.extend(xml_attrs)
            xml_attrs = []
            other_attrs.sort(_sorter)
            for a in other_attrs:
                self._do_attr(a.nodeName, a.value)
            W('>')

        # Push state, recurse, pop state.
        state, self.state = self.state, (ns_local, ns_rendered, xml_attrs)
        for c in _children(node):
            _implementation.handlers[c.nodeType](self, c)
        self.state = state

        if name: W('</%s>' % name)
Ejemplo n.º 24
0
    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 type(input) in _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 not in (SOAP.ENV, SOAP.ENV12):
            raise ParseException('Document has %r element, not %s' %
                                 ((elt.namespaceURI, elt.localName), (SOAP.ENV12, '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 in (SOAP.ENV, SOAP.ENV12):
            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 not in (SOAP.ENV, SOAP.ENV12):
            if self.header:
                raise ParseException('Header followed by "%r" element, not Body' % ((elt.namespaceURI, elt.localName),), 0,
                        elt, self.dom)
            else:
                raise ParseException('Document has "%r element, not Body' % ((elt.namespaceURI, elt.localName),), 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)
        else:

            # Don't set self.trailer_elements = []; if user didn't ask
            # for trailers we *want* to throw an exception.

            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)
Ejemplo n.º 25
0
    def parse(self, elt, ps):
        #if elt.localName != self.pname:
        #    elt = elt.getElementsByTagName(self.pname)[0]
        self.checkname(elt, ps)
        if self.type and \
        self.checktype(elt, ps) not in [ self.type, (None,None) ]:
            raise EvaluateException('Struct has wrong type', ps.Backtrace(elt))
        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 None
        repeatable_args = False
        for tc in self.ofwhat:
            if tc.repeatable:
                repeatable_args = True
                break

        if not repeatable_args:
            if count > len(self.ofwhat) and not self.hasextras:
                raise EvaluateException('Too many sub-elements', ps.Backtrace(elt))

        # Create the object.
        v = {}

        # Clone list of kids (we null it out as we process)
        c, crange = c[:], range(len(c))
        # Loop over all items we're expecting
        for i,what in [ (i, self.ofwhat[i]) for i in range(len(self.ofwhat)) ]:
            # Loop over all available kids
            for j,c_elt in [ (j, c[j]) for j in crange if c[j] ]:
                if what.name_match(c_elt):
                    # Parse value, and mark this one done.
                    try:
                        value = what.parse(c_elt, ps)
                    except EvaluateException, e:
                        e.str = '%s.%s: %s' % \
                                (self.pname or '?', what.aname or '?', e.str)
                        raise e
                    if what.repeatable:
                        if v.has_key(what.aname):
                            v[what.aname].append(value)
                        else:
                            v[what.aname] = [value]
                        c[j] = None
                        continue
                    else:
                        v[what.aname] = value
                    c[j] = None
                    break
                # No match; if it was supposed to be here, that's an error.
                if self.inorder and i == j:
                    raise EvaluateException('Out of order struct',
                            ps.Backtrace(c_elt))
            else:
                if not what.optional and not v.has_key(what.aname):
                    raise EvaluateException('Element "' + what.aname + \
                        '" missing from struct', ps.Backtrace(elt))
                if hasattr(what, 'default'):
                    v[what.aname] = what.default
Ejemplo n.º 26
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)
        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 callable(what): 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