Пример #1
0
    def endElementNS(self, name, qname):
        # Workaround two sax bugs
        if name[0] == None and name[1][0] == ' ':
            ns, name = None, name[1][1:]
        else:
            ns, name = tuple(name)

        name = fromXMLname(name)  # convert to SOAP 1.2 XML name encoding

        if self._next == "E":
            raise Error, "didn't get SOAP-ENV:Envelope"
        if self._next in ("HorB", "B"):
            raise Error, "didn't get SOAP-ENV:Body"

        cur = self.popFrame()
        attrs = cur.attrs

        idval = None

        if attrs.has_key((None, 'id')):
            idval = attrs[(None, 'id')]

            if self._ids.has_key(idval):
                raise Error, "duplicate id `%s'" % idval

            del attrs[(None, 'id')]

        root = 1

        if len(self._stack) == 3:
            if attrs.has_key((NS.ENC, 'root')):
                root = int(attrs[(NS.ENC, 'root')])

                # Do some preliminary checks. First, if root="0" is present,
                # the element must have an id. Next, if root="n" is present,
                # n something other than 0 or 1, raise an exception.

                if root == 0:
                    if idval == None:
                        raise Error, "non-root element must have an id"
                elif root != 1:
                    raise Error, "SOAP-ENC:root must be `0' or `1'"

                del attrs[(NS.ENC, 'root')]

        while 1:
            href = attrs.get((None, 'href'))
            if href:
                if href[0] != '#':
                    raise Error, "Non-local hrefs are not yet suppported."
                if self._data != None and \
                   string.join(self._data, "").strip() != '':
                    raise Error, "hrefs can't have data"

                href = href[1:]

                if self._ids.has_key(href):
                    data = self._ids[href]
                else:
                    data = RefHolder(name, self._stack[-1])

                    if self._refs.has_key(href):
                        self._refs[href].append(data)
                    else:
                        self._refs[href] = [data]

                del attrs[(None, 'href')]

                break

            kind = None

            if attrs:
                for i in NS.XSI_L:
                    if attrs.has_key((i, 'type')):
                        kind = attrs[(i, 'type')]
                        del attrs[(i, 'type')]

                if kind != None:
                    i = kind.find(':')
                    if i >= 0:
                        try:
                            kind = (self._prem[kind[:i]], kind[i + 1:])
                        except:
                            kind = (None, kind)
                    else:
                        # XXX What to do here? (None, kind) is just going to fail in convertType
                        #print "Kind with no NS:", kind
                        kind = (None, kind)

            null = 0

            if attrs:
                for i in (NS.XSI, NS.XSI2):
                    if attrs.has_key((i, 'null')):
                        null = attrs[(i, 'null')]
                        del attrs[(i, 'null')]

                if attrs.has_key((NS.XSI3, 'nil')):
                    null = attrs[(NS.XSI3, 'nil')]
                    del attrs[(NS.XSI3, 'nil')]

                ## Check for nil

                # check for nil='true'
                if type(null) in (StringType, UnicodeType):
                    if null.lower() == 'true':
                        null = 1

                # check for nil=1, but watch out for string values
                try:
                    null = int(null)
                except ValueError, e:
                    if not e[0].startswith("invalid literal for int()"):
                        raise e
                    null = 0

                if null:
                    if len(cur) or \
                        (self._data != None and string.join(self._data, "").strip() != ''):
                        raise Error, "nils can't have data"

                    data = None

                    break

            if len(self._stack) == 2:
                if (ns, name) == (NS.ENV, "Header"):
                    self.header = data = headerType(attrs=attrs)
                    self._next = "B"
                    break
                elif (ns, name) == (NS.ENV, "Body"):
                    self.body = data = bodyType(attrs=attrs)
                    self._next = ""
                    break
            elif len(self._stack) == 3 and self._next == None:
                if (ns, name) == (NS.ENV, "Fault"):
                    data = faultType()
                    self._next = None  # allow followons
                    break

            #print "\n"
            #print "data=", self._data
            #print "kind=", kind
            #print "cur.kind=", cur.kind
            #print "cur.rules=", cur.rules
            #print "\n"

            if cur.rules != None:
                rule = cur.rules

                if type(rule) in (StringType, UnicodeType):
                    rule = (None, rule)  # none flags special handling
                elif type(rule) == ListType:
                    rule = tuple(rule)

                #print "kind=",kind
                #print "rule=",rule

# XXX What if rule != kind?
                if callable(rule):
                    data = rule(string.join(self._data, ""))
                elif type(rule) == DictType:
                    data = structType(name=(ns, name), attrs=attrs)
                elif rule[1][:9] == 'arrayType':
                    data = self.convertType(cur.contents, rule, attrs)
                else:
                    data = self.convertType(string.join(self._data, ""), rule,
                                            attrs)

                break

            #print "No rules, using kind or cur.kind..."

            if (kind == None and cur.kind != None) or \
                (kind == (NS.ENC, 'Array')):
                kind = cur.kind

                if kind == None:
                    kind = 'ur-type[%d]' % len(cur)
                else:
                    kind = kind[1]

                if len(cur.namecounts) == 1:
                    elemsname = cur.names[0]
                else:
                    elemsname = None

                data = self.startArray((ns, name), kind, attrs, elemsname)

                break

            if len(self._stack) == 3 and kind == None and \
                len(cur) == 0 and \
                (self._data == None or string.join(self._data, "").strip() == ''):
                data = structType(name=(ns, name), attrs=attrs)
                break

            if len(cur) == 0 and ns != NS.URN:
                # Nothing's been added to the current frame so it must be a
                # simple type.

                #                 print "cur:", cur
                #                 print "ns:", ns
                #                 print "attrs:", attrs
                #                 print "kind:", kind

                if kind == None:
                    # If the current item's container is an array, it will
                    # have a kind. If so, get the bit before the first [,
                    # which is the type of the array, therefore the type of
                    # the current item.

                    kind = self._stack[-1].kind

                    if kind != None:
                        i = kind[1].find('[')
                        if i >= 0:
                            kind = (kind[0], kind[1][:i])
                    elif ns != None:
                        kind = (ns, name)

                if kind != None:
                    try:
                        data = self.convertType(string.join(self._data, ""),
                                                kind, attrs)
                    except UnknownTypeError:
                        data = None
                else:
                    data = None

                if data == None:
                    if self._data == None:
                        data = ''
                    else:
                        data = string.join(self._data, "")

                    if len(attrs) == 0:
                        try:
                            data = str(data)
                        except:
                            pass

                break

            data = structType(name=(ns, name), attrs=attrs)

            break
Пример #2
0
    def endElementNS(self, name, qname):
        # Workaround two sax bugs
        if name[0] == None and name[1][0] == " ":
            ns, name = None, name[1][1:]
        else:
            ns, name = tuple(name)

        name = fromXMLname(name)  # convert to SOAP 1.2 XML name encoding

        if self._next == "E":
            raise Error, "didn't get SOAP-ENV:Envelope"
        if self._next in ("HorB", "B"):
            raise Error, "didn't get SOAP-ENV:Body"

        cur = self.popFrame()
        attrs = cur.attrs

        idval = None

        if attrs.has_key((None, "id")):
            idval = attrs[(None, "id")]

            if self._ids.has_key(idval):
                raise Error, "duplicate id `%s'" % idval

            del attrs[(None, "id")]

        root = 1

        if len(self._stack) == 3:
            if attrs.has_key((NS.ENC, "root")):
                root = int(attrs[(NS.ENC, "root")])

                # Do some preliminary checks. First, if root="0" is present,
                # the element must have an id. Next, if root="n" is present,
                # n something other than 0 or 1, raise an exception.

                if root == 0:
                    if idval == None:
                        raise Error, "non-root element must have an id"
                elif root != 1:
                    raise Error, "SOAP-ENC:root must be `0' or `1'"

                del attrs[(NS.ENC, "root")]

        while 1:
            href = attrs.get((None, "href"))
            if href:
                if href[0] != "#":
                    raise Error, "Non-local hrefs are not yet suppported."
                if self._data != None and string.join(self._data, "").strip() != "":
                    raise Error, "hrefs can't have data"

                href = href[1:]

                if self._ids.has_key(href):
                    data = self._ids[href]
                else:
                    data = RefHolder(name, self._stack[-1])

                    if self._refs.has_key(href):
                        self._refs[href].append(data)
                    else:
                        self._refs[href] = [data]

                del attrs[(None, "href")]

                break

            kind = None

            if attrs:
                for i in NS.XSI_L:
                    if attrs.has_key((i, "type")):
                        kind = attrs[(i, "type")]
                        del attrs[(i, "type")]

                if kind != None:
                    i = kind.find(":")
                    if i >= 0:
                        try:
                            kind = (self._prem[kind[:i]], kind[i + 1 :])
                        except:
                            kind = (None, kind)
                    else:
                        # XXX What to do here? (None, kind) is just going to fail in convertType
                        # print "Kind with no NS:", kind
                        kind = (None, kind)

            null = 0

            if attrs:
                for i in (NS.XSI, NS.XSI2):
                    if attrs.has_key((i, "null")):
                        null = attrs[(i, "null")]
                        del attrs[(i, "null")]

                if attrs.has_key((NS.XSI3, "nil")):
                    null = attrs[(NS.XSI3, "nil")]
                    del attrs[(NS.XSI3, "nil")]

                ## Check for nil

                # check for nil='true'
                if type(null) in (StringType, UnicodeType):
                    if null.lower() == "true":
                        null = 1

                # check for nil=1, but watch out for string values
                try:
                    null = int(null)
                except ValueError, e:
                    if not e[0].startswith("invalid literal for int()"):
                        raise e
                    null = 0

                if null:
                    if len(cur) or (self._data != None and string.join(self._data, "").strip() != ""):
                        raise Error, "nils can't have data"

                    data = None

                    break

            if len(self._stack) == 2:
                if (ns, name) == (NS.ENV, "Header"):
                    self.header = data = headerType(attrs=attrs)
                    self._next = "B"
                    break
                elif (ns, name) == (NS.ENV, "Body"):
                    self.body = data = bodyType(attrs=attrs)
                    self._next = ""
                    break
            elif len(self._stack) == 3 and self._next == None:
                if (ns, name) == (NS.ENV, "Fault"):
                    data = faultType()
                    self._next = None  # allow followons
                    break

            # print "\n"
            # print "data=", self._data
            # print "kind=", kind
            # print "cur.kind=", cur.kind
            # print "cur.rules=", cur.rules
            # print "\n"

            if cur.rules != None:
                rule = cur.rules

                if type(rule) in (StringType, UnicodeType):
                    rule = (None, rule)  # none flags special handling
                elif type(rule) == ListType:
                    rule = tuple(rule)

                # print "kind=",kind
                # print "rule=",rule

                # XXX What if rule != kind?
                if callable(rule):
                    data = rule(string.join(self._data, ""))
                elif type(rule) == DictType:
                    data = structType(name=(ns, name), attrs=attrs)
                elif rule[1][:9] == "arrayType":
                    data = self.convertType(cur.contents, rule, attrs)
                else:
                    data = self.convertType(string.join(self._data, ""), rule, attrs)

                break

            # print "No rules, using kind or cur.kind..."

            if (kind == None and cur.kind != None) or (kind == (NS.ENC, "Array")):
                kind = cur.kind

                if kind == None:
                    kind = "ur-type[%d]" % len(cur)
                else:
                    kind = kind[1]

                if len(cur.namecounts) == 1:
                    elemsname = cur.names[0]
                else:
                    elemsname = None

                data = self.startArray((ns, name), kind, attrs, elemsname)

                break

            if (
                len(self._stack) == 3
                and kind == None
                and len(cur) == 0
                and (self._data == None or string.join(self._data, "").strip() == "")
            ):
                data = structType(name=(ns, name), attrs=attrs)
                break

            if len(cur) == 0 and ns != NS.URN:
                # Nothing's been added to the current frame so it must be a
                # simple type.

                #                 print "cur:", cur
                #                 print "ns:", ns
                #                 print "attrs:", attrs
                #                 print "kind:", kind

                if kind == None:
                    # If the current item's container is an array, it will
                    # have a kind. If so, get the bit before the first [,
                    # which is the type of the array, therefore the type of
                    # the current item.

                    kind = self._stack[-1].kind

                    if kind != None:
                        i = kind[1].find("[")
                        if i >= 0:
                            kind = (kind[0], kind[1][:i])
                    elif ns != None:
                        kind = (ns, name)

                if kind != None:
                    try:
                        data = self.convertType(string.join(self._data, ""), kind, attrs)
                    except UnknownTypeError:
                        data = None
                else:
                    data = None

                if data == None:
                    if self._data == None:
                        data = ""
                    else:
                        data = string.join(self._data, "")

                    if len(attrs) == 0:
                        try:
                            data = str(data)
                        except:
                            pass

                break

            data = structType(name=(ns, name), attrs=attrs)

            break
Пример #3
0
    def endElementNS(self, name, qname):
        # Workaround two sax bugs
        if name[0] == None and name[1][0] == ' ':
            ns, name = None, name[1][1:]
        else:
            ns, name = tuple(name)

        name = fromXMLname(name)  # convert to SOAP 1.2 XML name encoding

        if self._next == "E":
            raise Error, "didn't get SOAP-ENV:Envelope"
        if self._next in ("HorB", "B"):
            raise Error, "didn't get SOAP-ENV:Body"

        cur = self.popFrame()
        attrs = cur.attrs

        idval = None

        if attrs.has_key((None, 'id')):
            idval = attrs[(None, 'id')]

            if self._ids.has_key(idval):
                raise Error, "duplicate id `%s'" % idval

            del attrs[(None, 'id')]

        root = 1

        if len(self._stack) == 3:
            if attrs.has_key((NS.ENC, 'root')):
                root = int(attrs[(NS.ENC, 'root')])

                # Do some preliminary checks. First, if root="0" is present,
                # the element must have an id. Next, if root="n" is present,
                # n something other than 0 or 1, raise an exception.

                if root == 0:
                    if idval == None:
                        raise Error, "non-root element must have an id"
                elif root != 1:
                    raise Error, "SOAP-ENC:root must be `0' or `1'"

                del attrs[(NS.ENC, 'root')]

        while 1:
            href = attrs.get((None, 'href'))
            if href:
                if href[0] != '#':
                    raise Error, "only do local hrefs right now"
                if self._data != None and self._data.strip() != '':
                    raise Error, "hrefs can't have data"

                href = href[1:]

                if self._ids.has_key(href):
                    data = self._ids[href]
                else:
                    data = RefHolder(name, self._stack[-1])

                    if self._refs.has_key(href):
                        self._refs[href].append(data)
                    else:
                        self._refs[href] = [data]

                del attrs[(None, 'href')]

                break

            kind = None

            if attrs:
                for i in NS.XSI_L:
                    if attrs.has_key((i, 'type')):
                        kind = attrs[(i, 'type')]
                        del attrs[(i, 'type')]

                if kind != None:
                    i = kind.find(':')
                    if i >= 0:
                        kind = (self._prem[kind[:i]], kind[i + 1:])
                    else:
                        # XXX What to do here? (None, kind) is just going to fail in convertType
                        kind = (None, kind)

            null = 0

            if attrs:
                for i in (NS.XSI, NS.XSI2):
                    if attrs.has_key((i, 'null')):
                        null = attrs[(i, 'null')]
                        del attrs[(i, 'null')]

                if attrs.has_key((NS.XSI3, 'nil')):
                    null = attrs[(NS.XSI3, 'nil')]
                    del attrs[(NS.XSI3, 'nil')]

                null = int(null)

                if null:
                    if len(cur) or \
                        (self._data != None and self._data.strip() != ''):
                        raise Error, "nils can't have data"

                    data = None

                    break

            if len(self._stack) == 2:
                if (ns, name) == (NS.ENV, "Header"):
                    self.header = data = headerType(attrs=attrs)
                    self._next = "B"
                    break
                elif (ns, name) == (NS.ENV, "Body"):
                    self.body = data = bodyType(attrs=attrs)
                    self._next = ""
                    break
            elif len(self._stack) == 3 and self._next == None:
                if (ns, name) == (NS.ENV, "Fault"):
                    data = faultType()
                    self._next = ""
                    break

            if cur.rules != None:
                rule = cur.rules

                if type(rule) in (StringType, UnicodeType):
                    # XXX Need a namespace here
                    rule = (None, rule)
                elif type(rule) == ListType:
                    rule = tuple(rule)

# XXX What if rule != kind?
                if callable(rule):
                    data = rule(self._data)
                elif type(rule) == DictType:
                    data = structType(name=(ns, name), attrs=attrs)
                else:
                    data = self.convertType(self._data, rule, attrs)

                break

            if (kind == None and cur.kind != None) or \
                (kind == (NS.ENC, 'Array')):
                kind = cur.kind

                if kind == None:
                    kind = 'ur-type[%d]' % len(cur)
                else:
                    kind = kind[1]

                if len(cur.namecounts) == 1:
                    elemsname = cur.names[0]
                else:
                    elemsname = None

                data = self.startArray((ns, name), kind, attrs, elemsname)

                break

            if len(self._stack) == 3 and kind == None and \
                len(cur) == 0 and \
                (self._data == None or self._data.strip() == ''):
                data = structType(name=(ns, name), attrs=attrs)
                break

            if len(cur) == 0 and ns != NS.URN:
                # Nothing's been added to the current frame so it must be a
                # simple type.

                if kind == None:
                    # If the current item's container is an array, it will
                    # have a kind. If so, get the bit before the first [,
                    # which is the type of the array, therefore the type of
                    # the current item.

                    kind = self._stack[-1].kind

                    if kind != None:
                        i = kind[1].find('[')
                        if i >= 0:
                            kind = (kind[0], kind[1][:i])
                    elif ns != None:
                        kind = (ns, name)

                if kind != None:
                    try:
                        data = self.convertType(self._data, kind, attrs)
                    except UnknownTypeError:
                        data = None
                else:
                    data = None

                if data == None:
                    data = self._data or ''

                    if len(attrs) == 0:
                        try:
                            data = str(data)
                        except:
                            pass

                break

            data = structType(name=(ns, name), attrs=attrs)

            break

        if isinstance(data, compoundType):
            for i in range(len(cur)):
                v = cur.contents[i]
                data._addItem(cur.names[i], v, cur.subattrs[i])

                if isinstance(v, RefHolder):
                    v.parent = data

        if root:
            self._stack[-1].append(name, data, attrs)

        if idval != None:
            self._ids[idval] = data

            if self._refs.has_key(idval):
                for i in self._refs[idval]:
                    i.parent._placeItem(i.name, data, i.pos, i.subpos, attrs)

                del self._refs[idval]

        self.attrs[id(data)] = attrs

        if isinstance(data, anyType):
            data._setAttrs(attrs)

        self._data = None  # Stop accumulating