如果格式不恒定,如何在JSON对象中搜索关键字?

时间:2019-06-17 12:36:21

标签: android json

在我的android应用程序中,我已将表单数据保存在json中,此json的父对象是一个json对象,其中可能包含简单的键值对,JSON数组或子json对象。

父JSON对象的结构基本上在运行时发生变化,我必须添加一个函数,该函数可以查找针对任何键保存的值。

例如,如果我具有以下JSON,并且我想获取key5的值。有没有办法获得价值?

我想尝试的一种解决方案是遍历json,但是我无法检查json对象索引上存储的内容,这意味着它是简单的字符串,json数组还是子json对象。

{
    "key1": "value of key 1",
    "key2": "value of key 2",
    "key3": "value of key 3",
    "subjson": {
        "key4": "value of key 4",
        "key5": "value of key 5",
        "key6": "value of key 6"
    },
    "subjsonArray": [
        {
            "key7": "value of key 7",
            "key8": "value of key 8"
        },
        {
            "key9": "value of key 9",
            "key10": "value of key 10"
        }
    ]
}

有人可以帮我这个忙吗?任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:0)

这是处理json的示例

    JsonElement jsonElement = new Gson().fromJson("YOUR JSON", JsonElement.class);
    if(jsonElement.isJsonObject()){
        jsonElement.getAsJsonObject("key5");
    }else if(jsonElement.isJsonArray()){
        jsonElement.getAsJsonArray("key5");
    }

如果您需要遍历json,可以使用

Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for(Map.Entry<String,JsonElement> entry : entrySet){
    String key = entry.getKey();
    JsonElement value = jsonObject.get(entry.getKey()));
}

您需要将Gson导入您的项目

    dependencies {
        implementation 'com.google.code.gson:gson:2.8.5'
    }

有关如何使用Gson的更多信息:

https://github.com/google/gson

答案 1 :(得分:0)

首先让我这样说-在找到解决方案之前,您应该尝试解决非恒定的Json问题。

但是,如果超出您的控制范围,这可能会起作用。

此处理嵌套的JsonObject和/或JsonArray

您可以仅复制/粘贴这些功能。 您所要做的就是调用此函数-getValueFromNonConstantJson(...)

private void getValueFromNonConstantJson(String fullJson, String key) {
    Gson gson = new Gson();
    final Type mapType = new TypeToken<Map<String, Object>>(){}.getType();

    Map<String, Object> objectMap = gson.fromJson(fullJson, mapType);
    String value = "";

    value = getValueFromMap(objectMap, key);
}


private String getValueFromMap(Map<String, Object> objectMap, String key) {
    String result = "";

    // let's quickly check is the root object contains the key you want
    // if it does, you don't have to start the for loop at all
    if(objectMap.containsKey("key5")) {
        Object key5Value = objectMap.get("key5");
        if(key5Value instanceof JsonObject) {
            JsonObject jsonObject = (JsonObject) key5Value;
            result = getValueFromJsonObject(jsonObject, key);
        } else if (key5Value instanceof JsonArray) {
            JsonArray jsonArray = (JsonArray) key5Value;
            result = getValueFromJsonArray(jsonArray, key);
        }
    } else {
        for(Map.Entry<String, Object> entry : objectMap.entrySet()) {
            if(entry.getValue() instanceof JsonObject) {
                JsonObject jsonObject = (JsonObject) entry.getValue();
                result = getValueFromJsonObject(jsonObject, key);

                if(!result.isEmpty()) {
                    // you found it.
                    break;
                }

            } else if (entry.getValue() instanceof JsonArray) {
                JsonArray jsonArray = (JsonArray) entry.getValue();
                result = getValueFromJsonArray(jsonArray, key);

                if(!result.isEmpty()) {
                    // you found it.
                    break;
                }
            }
        }
    }

    return result;
}


private String getValueFromJsonObject(JsonObject subJsonObject, String key) {
    String value = "";

    Gson gson = new Gson();
    final Type mapType = new TypeToken<Map<String, Object>>(){}.getType();

    Map<String, Object> objectMap = gson.fromJson(subJsonObject, mapType);

    value = getValueFromMap(objectMap, key);
    return value;
}


private String getValueFromJsonArray(JsonArray subJsonArray, String key) {
    String value = "";

    Gson gson = new Gson();

    Object[] objectArr = gson.fromJson(subJsonArray, Object[].class);

    for(Object object : objectArr) {
        if(object instanceof Map) {
            Map<String, Object> objectMap = (Map<String, Object>) object;
            value = getValueFromMap(objectMap, key);

            if(!value.isEmpty()) {
                break;
            }
        }
    }

    return value;
}

答案 2 :(得分:0)

使用JSONObject可以实现

01,09,65,80 -> 80,65,09,01
65,11,76,32 -> 32,76,11,65
 private Object interateNestedJson(JSONObject jsonObject, String keySearch) {

        for (Iterator<String> it = jsonObject.keys(); it.hasNext(); ) {

            try {
                String jsonKey = it.next();
                Object jsonValue = jsonObject.get(jsonKey);

                if (jsonValue instanceof JSONArray) {
                    Object foundInArray = iterateArray((JSONArray) jsonValue, keySearch);
                    if(foundInArray != null) {
                        return foundInArray;
                    }

                } else if (jsonValue instanceof JSONObject) {
                    Object foundInObject = interateNestedJson(jsonObject, keySearch);
                    if(foundInObject != null) {
                        return foundInObject;
                    }

                } else {
                    return jsonValue; // return primitive value
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

您就可以像这样开始搜索

private Object iterateArray(JSONArray jsonArray, String keySearch) throws JSONException {
        for (int i = 0; i < jsonArray.length(); i++) {
            Object jsonObject = jsonArray.get(i);
            if (jsonObject instanceof JSONObject) {
                Object inNested = interateNestedJson((JSONObject) jsonObject, keySearch);
                if (inNested != null) {
                    return inNested;
                }
            } else if (jsonObject instanceof JSONArray) {
                Object inArray = iterateArray((JSONArray) jsonObject, keySearch);
                if (inArray != null) {
                    return inArray;
                }
            }
        }
        return null;
    }

我现在没有时间进行测试,如果出现错误,我将在以后尝试予以修复

答案 3 :(得分:0)

使用翻新,您可以这样实现:

下面是 Model 类,由于未定义 JsonResponse 结构而扩展了 JsonElement

public class JsonResponse extends JsonElement {

    //Key will be of type JsonElement
    @SerializedName("key1")
    public JsonElement key1;

    //Return type is JsonElement since it is decided at Runtime
    public JsonElement getKey1() {
        if (key1 instanceof JsonArray) {
            List<JsonObject> objectList = getArray(key1);
            return (JsonElement) objectList;            //If key is of type JsonArray then return JsonArray
        } else {
            return getObject(key1);                      //If key is of type JsonObject then return JsonObject
        }
    }

    public void setKey1(JsonElement key1) {
        this.key1 = key1;
    }

    private JsonObject getObject(JsonElement data) {
        Type type = new TypeToken<JsonObject>() {}.getType();
        return new Gson().fromJson(data, type);
    }


    private List<JsonObject> getArray(JsonElement data) {
        Type type = new TypeToken<List<JsonObject>>() {}.getType();
        return new Gson().fromJson(((JsonObject) data).get("key1"), type);
    }

    //Method from super class
    @Override
    public JsonElement deepCopy() {
        return null;
    }
}

可以为未定义返回类型的keys重复相同的过程。 然后,在您的ClassA中,您可以通过直接访问key1类中的JsonResponse元素来获取数据。

在您的ClassA中,检查此元素key1是否为JsonArray类型,并相应地获取数据。