检查嵌套JSON中是否存在密钥

时间:2021-01-02 23:46:39

I am stuck in a situation where I need to check whether a key exists in a nested JSON object. By nested JSON Object that I am having a JSON object inside the parent JSON object as the value of one of its key. So i need to check whether this key exists in entire JSON object. I am getting the below data as a String object. I know I can parse this String object to get JSON object.

我陷入了需要检查嵌套JSON对象中是否存在密钥的情况。通过嵌套的JSON对象,我在父JSON对象中有一个JSON对象作为其键之一的值。所以我需要检查这个键是否存在于整个JSON对象中。我将以下数据作为String对象获取。我知道我可以解析这个String对象来获取JSON对象。

{
"claim_loss_type_cd": "TEL",
"claim_type": "002",
"claim_reason": "001",
"policy_number": "1234kk3366ff664",
"info": {
    "ApplicationContext": {
        "country": "US"
    }
  }
}

I have used containsKey() method to check the key existence in the main JSON object and it works. But for checking any internal JSON object like "info" I need to parse that Object again to JSON object and then check the key again.

我已经使用containsKey()方法来检查主JSON对象中的密钥存在并且它可以工作。但是为了检查任何内部JSON对象,比如“info”,我需要再次将该Object解析为JSON对象,然后再次检查密钥。

        String jsonString = "My JSON String here";
        JSONObject finalResponse = new JSONObject(jsonString);
        finalResponse.containsKey("country"); // will return false
        JSONObject intermediateResponse = (JSONObject)finalResponse.get("info");
        intermediateResponse.containsKey("country"); // will return true

So is there any better way, any API or method which can check inside any internal JSON object as well without the need of parsing the internal JSON object. I am using com.ibm.json.java.JSONObject.JSONObject() native IBM library for Websphere Application Server and No additional JSON parsers I am using.

那么有没有更好的方法,任何可以在任何内部JSON对象内部检查的API或方法,而无需解析内部JSON对象。我正在为Websphere Application Server使用com.ibm.json.java.JSONObject.JSONObject()本机IBM库,而我正在使用其他JSON解析器。

Considering the above JSON, like "claim_type" is a key in parent JSON object but "info" in itself a JSON object. So what i need to do is to check whether a key exists in complete JSON, either in parent or any of its child JSON object like key "country" here in example.

考虑到上面的JSON,像“claim_type”是父JSON对象中的键,但“info”本身就是一个JSON对象。所以我需要做的是检查一个密钥是否存在于完整的JSON中,在父代或其任何子JSON对象中,如示例中的键“country”。

EDIT:

Thanks to @chsdk I came to a solution. But if anyone else came to any solution using some other API, please respond, because below solution is taking recursion into account & might have big Space/Time Complexity.

感谢@chsdk,我找到了解决方案。但是如果有其他人使用其他API来解决任何问题,请回复,因为以下解决方案正在考虑递归并且可能具有很大的空间/时间复杂性。

public static boolean checkKey(JSONObject object, String searchedKey) {
    boolean exists = object.containsKey(searchedKey);
    if(!exists) {      
         Set<String> keys = object.keySet();
         for(String key : keys){
             if ( object.get(key) instanceof JSONObject ) {
                    exists = checkKey((JSONObject)object.get(key), searchedKey);
            }
         }
    }
    return exists;
}

3 个解决方案

#1


4  

You can use JSONObject to parse your json and use its has(String key) method to check wether a key exists in this Json or not:

您可以使用JSONObject来解析您的json并使用其has(String key)方法来检查此Json中是否存在密钥:

 String str="{\"claim_loss_type_cd\": \"TEL\",\"claim_type\":\"002\",\"claim_reason\": \"001\",\"policy_number\":\"1234kk3366ff664\",\"info\": {\"ApplicationContext\":{\"country\": \"US\"}}}";
 Object obj=JSONValue.parse(str);
 JSONObject json = (JSONObject) obj;
 //Then use has method to check if this key exists or not
 System.out.println(json.has("claim_type")); //Returns true

EDIT:

Or better you can simply check if the JSON String contains this key value, for example with indexOf() method:

或者更好的是,您只需检查JSON字符串是否包含此键值,例如使用indexOf()方法:

String str="{\"claim_loss_type_cd\": \"TEL\",\"claim_type\":\"002\",\"claim_reason\": \"001\",\"policy_number\":\"1234kk3366ff664\",\"info\": {\"ApplicationContext\":{\"country\": \"US\"}}}";
System.out.println(str.indexOf("claim_type")>-1); //Returns true

EDIT 2:

Take a look at this method, it iterates over the nested objects to check if the key exists.

看一下这个方法,它迭代嵌套对象以检查密钥是否存在。

public boolean keyExists(JSONObject  object, String searchedKey) {
    boolean exists = object.has(searchedKey);
    if(!exists) {      
        Iterator<?> keys = object.keys();
        while( keys.hasNext() ) {
            String key = (String)keys.next();
            if ( object.get(key) instanceof JSONObject ) {
                    exists = keyExists(object.get(key), searchedKey);
            }
        }
    }
    return exists;
}

Object obj=JSONValue.parse(str);
JSONObject json = (JSONObject) obj;
System.out.println(keyExists(json, "country")); //Returns true

#2


0  

A ready-to-go method with correct casting of types:

一个正确的方法,正确的类型转换:

/**
 * JSONObject contains the given key. Search is also done in nested 
 * objects recursively.
 *
 * @param json JSONObject to serach in.
 * @param key Key name to search for.
 * @return Key is found.
 */
public static boolean hasKey(
  JSONObject json,
  String key) {

  boolean exists = json.has(key);
  Iterator<?> keys;
  String nextKey;

  if (!exists) {

    keys = json.keys();

    while (keys.hasNext()) {
      nextKey = (String) keys.next();

      try {
        if (json.get(nextKey) instanceof JSONObject) {
          exists =
            hasKey(
              json.getJSONObject(nextKey),
              key);
        }
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }
  }

  return exists;
}

#3


0  

Both solutions, which suggest to iterate the JsonObject recursively, have a little bug: they don't break the iteration when they finally find the searched key. So you have to break the while-loop, otherwise the loop will continue and if there is a next key, it will check this key and so on. The code example, which searches for the "country"-key only works, because 'country' is coincidentally the last key in its JsonObject.

建议以递归方式迭代JsonObject的两个解决方案都有一个小错误:当它们最终找到搜索到的密钥时,它们不会破坏迭代。所以你必须打破while循环,否则循环将继续,如果有下一个键,它将检查此键,依此类推。搜索“country”-key的代码示例仅起作用,因为“country”巧合地是其JsonObject中的最后一个键。

Example:

 /* ... */
    while (keys.hasNext()) {
          nextKey = (String) keys.next();

          try {
            if (json.get(nextKey) instanceof JSONObject) {
              exists = hasKey(json.getJSONObject(nextKey), key);

              if(exists){
                  break;
              }

            }
          } catch (JSONException e) {
            e.printStackTrace();
          }
        }
    /* ... */

#1


4  

You can use JSONObject to parse your json and use its has(String key) method to check wether a key exists in this Json or not:

您可以使用JSONObject来解析您的json并使用其has(String key)方法来检查此Json中是否存在密钥:

 String str="{\"claim_loss_type_cd\": \"TEL\",\"claim_type\":\"002\",\"claim_reason\": \"001\",\"policy_number\":\"1234kk3366ff664\",\"info\": {\"ApplicationContext\":{\"country\": \"US\"}}}";
 Object obj=JSONValue.parse(str);
 JSONObject json = (JSONObject) obj;
 //Then use has method to check if this key exists or not
 System.out.println(json.has("claim_type")); //Returns true

EDIT:

Or better you can simply check if the JSON String contains this key value, for example with indexOf() method:

或者更好的是,您只需检查JSON字符串是否包含此键值,例如使用indexOf()方法:

String str="{\"claim_loss_type_cd\": \"TEL\",\"claim_type\":\"002\",\"claim_reason\": \"001\",\"policy_number\":\"1234kk3366ff664\",\"info\": {\"ApplicationContext\":{\"country\": \"US\"}}}";
System.out.println(str.indexOf("claim_type")>-1); //Returns true

EDIT 2:

Take a look at this method, it iterates over the nested objects to check if the key exists.

看一下这个方法,它迭代嵌套对象以检查密钥是否存在。

public boolean keyExists(JSONObject  object, String searchedKey) {
    boolean exists = object.has(searchedKey);
    if(!exists) {      
        Iterator<?> keys = object.keys();
        while( keys.hasNext() ) {
            String key = (String)keys.next();
            if ( object.get(key) instanceof JSONObject ) {
                    exists = keyExists(object.get(key), searchedKey);
            }
        }
    }
    return exists;
}

Object obj=JSONValue.parse(str);
JSONObject json = (JSONObject) obj;
System.out.println(keyExists(json, "country")); //Returns true

#2


0  

A ready-to-go method with correct casting of types:

一个正确的方法,正确的类型转换:

/**
 * JSONObject contains the given key. Search is also done in nested 
 * objects recursively.
 *
 * @param json JSONObject to serach in.
 * @param key Key name to search for.
 * @return Key is found.
 */
public static boolean hasKey(
  JSONObject json,
  String key) {

  boolean exists = json.has(key);
  Iterator<?> keys;
  String nextKey;

  if (!exists) {

    keys = json.keys();

    while (keys.hasNext()) {
      nextKey = (String) keys.next();

      try {
        if (json.get(nextKey) instanceof JSONObject) {
          exists =
            hasKey(
              json.getJSONObject(nextKey),
              key);
        }
      } catch (JSONException e) {
        e.printStackTrace();
      }
    }
  }

  return exists;
}

#3


0  

Both solutions, which suggest to iterate the JsonObject recursively, have a little bug: they don't break the iteration when they finally find the searched key. So you have to break the while-loop, otherwise the loop will continue and if there is a next key, it will check this key and so on. The code example, which searches for the "country"-key only works, because 'country' is coincidentally the last key in its JsonObject.

建议以递归方式迭代JsonObject的两个解决方案都有一个小错误:当它们最终找到搜索到的密钥时,它们不会破坏迭代。所以你必须打破while循环,否则循环将继续,如果有下一个键,它将检查此键,依此类推。搜索“country”-key的代码示例仅起作用,因为“country”巧合地是其JsonObject中的最后一个键。

Example:

 /* ... */
    while (keys.hasNext()) {
          nextKey = (String) keys.next();

          try {
            if (json.get(nextKey) instanceof JSONObject) {
              exists = hasKey(json.getJSONObject(nextKey), key);

              if(exists){
                  break;
              }

            }
          } catch (JSONException e) {
            e.printStackTrace();
          }
        }
    /* ... */