Follow searchpath through the datatree in searchtree
    and report if there exists a value of type dtype
    searchpath is a list of keys/indices
    If dtype is None check for any value
    you can also supply a tuple  to dtype

def is_data_value(searchpath, searchtree, dtype = None, empty_is_false = False):
    """
    Follow searchpath through the datatree in searchtree
    and report if there exists a value of type dtype
    searchpath is a list of keys/indices
    If dtype is None check for any value
    you can also supply a tuple  to dtype
    """
    if isinstance(searchpath, (str, unicode, int)):
        searchpath = [searchpath]

    if not isinstance(searchpath, (list, tuple)):
        return False

    for d in searchpath:
        if isinstance(searchtree, dict):
            if not d in searchtree.keys():
                return False

        elif isinstance(searchtree, (list, tuple)):
            if (not isinstance(d, int) or (d >= 0 and d >= len(searchtree)) or (d < 0 and -d > len(searchtree))):
                return False

        else:
            return False

        searchtree = searchtree[d]

    if dtype == None and not (empty_is_false and searchtree == None):
        return True

    if empty_is_false and searchtree in (None, "", {}, []):
        return False

    if isinstance(dtype, tuple):
        dtype = list(dtype)

    elif not isinstance(dtype, list):
        dtype = [dtype]

    if float in dtype and not int in dtype:
        dtype.append(int)

    if str in dtype or unicode in dtype or 'string' in dtype:
        for dtp in (str, unicode, 'string'):
            while dtp in dtype:
                dtype.remove(dtp)
        dtype.extend([str, unicode])

    if list in dtype or tuple in dtype or 'list' in dtype:
        for dtp in (list, tuple, 'list'):
            while dtp in dtype:
                dtype.remove(dtp)
        dtype.extend([list, tuple])

    dtype = tuple(dtype)

    return bool(isinstance(searchtree, dtype))