def unmarshall(self, types, strict=True):
        "Convert to python values the current serialized xml element"
        # types is a dict of {tag name: convertion function}
        # strict=False to use default type conversion if not specified
        # example: types={'p': {'a': int,'b': int}, 'c': [{'d':str}]}
        #   expected xml: <p><a>1</a><b>2</b></p><c><d>hola</d><d>chau</d>
        #   returnde value: {'p': {'a':1,'b':2}, `'c':[{'d':'hola'},{'d':'chau'}]}
        d = {}
        for node in self():
            name = str(node.get_local_name())
            ref_name_type = None
            # handle multirefs: href="#id0"
            if 'href' in node.attributes().keys():
                href = node['href'][1:]
                for ref_node in self(root=True)("multiRef"):
                    if ref_node['id'] == href:
                        node = ref_node
                        ref_name_type = ref_node['xsi:type'].split(":")[1]
                        break
            try:
                fn = types[name]
            except (KeyError, ), e:
                if node.get_namespace_uri("soapenc"):
                    fn = None # ignore multirefs!
                elif 'xsi:type' in node.attributes().keys():
                    xsd_type = node['xsi:type'].split(":")[1]
                    fn = REVERSE_TYPE_MAP[xsd_type]
                elif strict:
                    raise TypeError(u"Tag: %s invalid (type not found)" % (name,))
                else:
                    # if not strict, use default type conversion
                    fn = unicode
            
            if isinstance(fn, list):
                # append to existing list (if any) - unnested dict arrays -
                value = d.setdefault(name, [])
                children = node.children()
                for child in (children and children() or []): # Readability counts
                    value.append(child.unmarshall(fn[0], strict))
            
            elif isinstance(fn, tuple):
                value = []
                _d = {}
                children = node.children()
                as_dict = len(fn) == 1 and isinstance(fn[0], dict)

                for child in (children and children() or []): # Readability counts
                    if as_dict:
                        _d.update(child.unmarshall(fn[0], strict)) # Merging pairs
                    else:
                        value.append(child.unmarshall(fn[0], strict))
                if as_dict:
                    value.append(_d)

                if name in d:
                    _tmp = list(d[name])
                    _tmp.extend(value)
                    value = tuple(_tmp)
                else:
                    value = tuple(value)
            
            elif isinstance(fn, dict):
                ##if ref_name_type is not None:
                ##    fn = fn[ref_name_type]
                children = node.children()
                value = children and children.unmarshall(fn, strict)
            else:
                if fn is None: # xsd:anyType not unmarshalled
                    value = node
                elif str(node) or fn == str:
                    try:
                        # get special deserialization function (if any)
                        fn = TYPE_UNMARSHAL_FN.get(fn,fn) 
                        if fn == str:
                            # always return an unicode object:
                            value = unicode(node)
                        else:
                            value = fn(unicode(node))
                    except (ValueError, __HOLE__), e:
                        raise ValueError(u"Tag: %s: %s" % (name, unicode(e)))
                else:
                    value = None
            d[name] = value
        return d
dataset/ETHPy150Open uwdata/termite-visualizations/web2py/gluon/contrib/pysimplesoap/simplexml.py/SimpleXMLElement.unmarshall