How to parse a dynamic JSON key in a Nested JSON result?

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

I have a JSON result in the following format which JSON Lint shows this as a "Valid Response".

My question is: how do I access the content of "question_mark" since "141", "8911", etc are all dynamic values?

My sample code for accessing value of "product".

//Consider I have the first JSONObject of the "search_result" array and  //I access it's "product" value as below. String product = jsonObject.optString("product"); //where jsonObject is of type JSONObject. //product now contains "abc". 

JSON:

{  "status": "OK",  "search_result": [              {                 "product": "abc",                 "id": "1132",                 "question_mark": {                     "141": {                         "count": "141",                         "more_description": "this is abc",                         "seq": "2"                     },                     "8911": {                         "count": "8911",                         "more_desc": "this is cup",                         "seq": "1"                     }                 },                 "name": "some name",                 "description": "This is some product"             },             {                 "product": "XYZ",                 "id": "1129",                 "question_mark": {                     "379": {                         "count": "379",                         "more_desc": "this is xyz",                         "seq": "5"                     },                     "845": {                         "count": "845",                         "more_desc": "this is table",                         "seq": "6"                     },                     "12383": {                         "count": "12383",                         "more_desc": "Jumbo",                         "seq": "4"                     },                     "257258": {                         "count": "257258",                         "more_desc": "large",                         "seq": "1"                     }                 },                 "name": "some other name",                 "description": "this is some other product"             }        ] } 

My question title "dynamic key" could be wrong but I don't know at this point what's a better name for this issue.

Any help would be greatly appreciated!

回答1:

Use JSONObject keys() to get the key and then iterate each key to get to the dynamic value.

Roughly the code will look like:

     // searchResult refers to the current element in the array "search_result"     JSONObject questionMark = searchResult.getJSONObject("question_mark");     Iterator keys = questionMark.keys();      while(keys.hasNext()) {         // loop to get the dynamic key         String currentDynamicKey = (String)keys.next();          // get the value of the dynamic key         JSONObject currentDynamicValue = questionMark.getJSONObject(currentDynamicKey);          // do something here with the value...     }  


回答2:

Another possibility is to use Gson (Note, I use lombok here to generates getters/setters, toString, etc):

package so7304002;  import java.util.List; import java.util.Map;  import lombok.AccessLevel; import lombok.Data; import lombok.NoArgsConstructor;  import com.google.gson.Gson; import com.google.gson.annotations.SerializedName; import com.google.gson.reflect.TypeToken;  @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class JsonDemo {     @Data     private static class MyMap {         private int count;          @SerializedName("more_description")         private String moreDescription;          private int seq;     }      @Data     private static class Product {         private String product;          private int id;          @SerializedName("question_mark")         private Map questionMark;     }      @Data     private static class MyObject {         private String status;          @SerializedName("search_result")         private List searchResult;     }      private static final String INPUT = ""; // your JSON      public static void main(final String[] arg) {         final MyObject fromJson = new Gson().fromJson(INPUT,              new TypeToken(){}.getType());         final List searchResult = fromJson.getSearchResult();         for (final Product p : searchResult) {             System.out.println("product: " + p.getProduct()                  + "\n" + p.getQuestionMark()+ "\n");         }     } } 

Output:

product: abc {141=JsonDemo.MyMap(count=141, moreDescription=this is abc, seq=2),   8911=JsonDemo.MyMap(count=8911, moreDescription=null, seq=1)}  product: XYZ {379=JsonDemo.MyMap(count=379, moreDescription=null, seq=5),   845=JsonDemo.MyMap(count=845, moreDescription=null, seq=6),   12383=JsonDemo.MyMap(count=12383, moreDescription=null, seq=4),   257258=JsonDemo.MyMap(count=257258, moreDescription=null, seq=1)} 


回答3:

The same thing can also be done using GSON, but instead of using GSON converter adapter to convert into to POJO. we will parse it manually. which gives us flexibility in case of dynamic JSON data.
let's say the JSON format is like below in my case.

{   "dateWiseContent": {     "02-04-2017": [       {         "locality": " Cross Madian Cross Rd No 4"       }     ],     "04-04-2017": [       {         "locality": "Dsilva Wadi"       },       {         "locality": " Cross Madian Cross Rd No 4",         "appointments": []       }     ]   } } 

in this case the dateWiseContent has dynamic object keys so we will parse this json string using JsonParser class.

  //parsing string response to json object  JsonObject jsonObject = (JsonObject) new JsonParser().parse(resource);   //getting root object  JsonObject dateWiseContent = jsonObject.get("dateWiseContent").getAsJsonObject(); 

get the dynamic keys using Map.Entry as given below

  // your code goes here          for (Map.Entry entry : dateWiseContent.entrySet()) {             //this gets the dynamic keys             String  dateKey = entry.getKey();              //you can get any thing now json element,array,object according to json.              JsonArray jsonArrayDates = entry.getValue().getAsJsonArray();             int appointmentsSize = jsonArrayDates.size();               for (int count = 0; count 

similarly any level of dynamic json can be parsed using Map.Entry



回答4:

An example of using Google Gson

JSON data from the question:

{     "status": "OK",     "search_result": [         {             "product": "abc",             "id": "1132",             "question_mark": {                 "141": {                     "count": "141",                     "more_description": "this is abc",                     "seq": "2"                 },                 "8911": {                     "count": "8911",                     "more_desc": "this is cup",                     "seq": "1"                 }             },             "name": "some name",             "description": "This is some product"         },         {             "product": "XYZ",             "id": "1129",             "question_mark": {                 "379": {                     "count": "379",                     "more_desc": "this is xyz",                     "seq": "5"                 },                 "845": {                     "count": "845",                     "more_desc": "this is table",                     "seq": "6"                 },                 "12383": {                     "count": "12383",                     "more_desc": "Jumbo",                     "seq": "4"                 },                 "257258": {                     "count": "257258",                     "more_desc": "large",                     "seq": "1"                 }             },             "name": "some other name",             "description": "this is some other product"         }     ] } 

Example code:

import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject;  public class GsonExercise {     public static void main(String[] args) {         String jsonString = "{\"status\":\"OK\",\"search_result\":[{\"product\":\"abc\",\"id\":\"1132\",\"question_mark\":{\"141\":{\"count\":\"141\",\"more_description\":\"this is abc\",\"seq\":\"2\"},\"8911\":{\"count\":\"8911\",\"more_desc\":\"this is cup\",\"seq\":\"1\"}},\"name\":\"some name\",\"description\":\"This is some product\"},{\"product\":\"XYZ\",\"id\":\"1129\",\"question_mark\":{\"379\":{\"count\":\"379\",\"more_desc\":\"this is xyz\",\"seq\":\"5\"},\"845\":{\"count\":\"845\",\"more_desc\":\"this is table\",\"seq\":\"6\"},\"12383\":{\"count\":\"12383\",\"more_desc\":\"Jumbo\",\"seq\":\"4\"},\"257258\":{\"count\":\"257258\",\"more_desc\":\"large\",\"seq\":\"1\"}},\"name\":\"some other name\",\"description\":\"this is some other product\"}]}";         JsonObject jobj = new Gson().fromJson(jsonString, JsonObject.class);         JsonArray ja = jobj.get("search_result").getAsJsonArray();         ja.forEach(el -> {             System.out.println("product: " + el.getAsJsonObject().get("product").getAsString());             JsonObject jo = el.getAsJsonObject().get("question_mark").getAsJsonObject();                         jo.entrySet().stream().forEach(qm -> {                 String key = qm.getKey();                 JsonElement je = qm.getValue();                 System.out.println("key: " + key);                 JsonObject o = je.getAsJsonObject();                 o.entrySet().stream().forEach(prop -> {                     System.out.println("\tname: " + prop.getKey() + " (value: " + prop.getValue().getAsString() + ")");                 });             });             System.out.println("");         });     }  } 

Output:

product: abc key: 141     name: count (value: 141)     name: more_description (value: this is abc)     name: seq (value: 2) key: 8911     name: count (value: 8911)     name: more_desc (value: this is cup)     name: seq (value: 1)  product: XYZ key: 379     name: count (value: 379)     name: more_desc (value: this is xyz)     name: seq (value: 5) key: 845     name: count (value: 845)     name: more_desc (value: this is table)     name: seq (value: 6) key: 12383     name: count (value: 12383)     name: more_desc (value: Jumbo)     name: seq (value: 4) key: 257258     name: count (value: 257258)     name: more_desc (value: large)     name: seq (value: 1) 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!