'Converts an element into JSON
@param element: the element
@param native: use native mode for attributes'

@classmethod
def __element2json(cls, element, native=False):

    TAG = cls.TAG
    ATTRIBUTE = cls.ATTRIBUTE
    PREFIX = cls.PREFIX
    element2json = cls.__element2json
    if (element.tag == TAG.list):
        obj = []
        append = obj.append
        for child in element:
            tag = child.tag
            if (not isinstance(tag, basestring)):
                continue
            if (tag[0] == '{'):
                tag = tag.rsplit('}', 1)[1]
            child_obj = element2json(child, native=native)
            if child_obj:
                append(child_obj)
        return obj
    else:
        obj = {}
        iterchildren = element.iterchildren
        xpath = element.xpath
        is_single = (lambda t, a, v: (len(xpath(("%s[@%s='%s']" % (t, a, v)))) == 1))
        for child in iterchildren(tag=etree.Element):
            tag = child.tag
            if (tag[0] == '{'):
                tag = tag.rsplit('}', 1)[1]
            collapse = True
            single = False
            attributes = child.attrib
            if native:
                if (tag == TAG.resource):
                    resource = attributes.get(ATTRIBUTE.name)
                    tag = ('%s_%s' % (PREFIX.resource, resource))
                    collapse = False
                elif (tag == TAG.options):
                    r = attributes.get(ATTRIBUTE.resource)
                    tag = ('%s_%s' % (PREFIX.options, r))
                    single = is_single(TAG.options, ATTRIBUTE.resource, r)
                elif (tag == TAG.reference):
                    f = attributes.get(ATTRIBUTE.field)
                    tag = ('%s_%s' % (PREFIX.reference, f))
                    single = is_single(TAG.reference, ATTRIBUTE.field, f)
                elif (tag == TAG.data):
                    tag = attributes.get(ATTRIBUTE.field)
                    single = is_single(TAG.data, ATTRIBUTE.field, tag)
            else:
                for s in iterchildren(tag=tag):
                    if (single is True):
                        single = False
                        break
                    else:
                        single = True
            child_obj = element2json(child, native=native)
            if ((child_obj is not None) and (child_obj != '')):
                if (tag not in obj):
                    if (single and collapse):
                        obj[tag] = child_obj
                    else:
                        obj[tag] = [child_obj]
                else:
                    if (type(obj[tag]) is not list):
                        obj[tag] = [obj[tag]]
                    obj[tag].append(child_obj)
        attributes = element.attrib
        skip_text = False
        tag = element.tag
        numeric = False
        for a in attributes:
            v = attributes[a]
            if native:
                if ((a == ATTRIBUTE.name) and (tag == TAG.resource)):
                    continue
                if ((a == ATTRIBUTE.resource) and (tag == TAG.options)):
                    continue
                if ((a == ATTRIBUTE.field) and (tag in (TAG.data, TAG.reference))):
                    continue
                if (a == ATTRIBUTE.value):
                    try:
                        v = json.loads(v)
                    except:
                        pass
            elif (a == ATTRIBUTE.value):
                try:
                    obj[TAG.item] = json.loads(v)
                except:
                    pass
                else:
                    skip_text = True
                continue
            elif ((a == ATTRIBUTE.type) and (v == 'numeric')):
                numeric = True
                continue
            obj[(PREFIX.attribute + a)] = v
        if (element.text and (not skip_text)):
            represent = cls.xml_decode(element.text)
            if numeric:
                try:
                    float_represent = float(represent.replace(',', ''))
                    int_represent = int(float_represent)
                    if (int_represent == float_represent):
                        represent = int_represent
                    else:
                        represent = float_represent
                except:
                    pass
            obj[PREFIX.text] = represent
        if ((len(obj) == 1) and (obj.keys()[0] in (PREFIX.text, TAG.item, TAG.list))):
            obj = obj[obj.keys()[0]]
        return obj
