1
votes

I am receiving json and am trying to operate on it using the JSONObject and JSONArray classes. I have nested objects and need to determine if those nested objects are arrays or objects. The problem is that if I assume it is an object and it is actually an array, when I get call getJSONObject, an exception is raised. I'm wondering if the only way to do this is just to add try/catch blocks or if there is a better way to do this. For example, say I have:

{"key1": "val1",
 "key2": {"level2": {"level3": "val3"}}
}

I may also have the level2 element with multiple values and coming in as an array:

{"key1": "val1",
 "key2": {"level2": [{"level3": "val3"}]}
}

How would I extract the level2 object (as an object) and determine if it is an object or an array? Is the only way to really do this using string manipulation?

If I do something like:

jsonObj.getJSONObject("key2").getJSONObject("level2");

It will result in an error: "org.json.JSONException: JSONObject["level2"] is not a JSONObject and conversly, if I call getJSONArray("level2") and level2 is not an array I will get an error indicating it is not an array.

4
I think the solution here is to name the keys better and just know what you're trying to parse beforehand. In other words, have a consistent schema - OneCricketeer
The problem is that the json is coming from an XML to JSON converter and if the json schema is intended to have an element as an array, but the element only has a single element, the converter has no way to know that the single element is intended to be just an object or a single element in an array. - GregH
which library you are using for json parsing - Sahil
The converter should know the difference between a single element array and an object. - OneCricketeer
org.json library - GregH

4 Answers

2
votes

You can use optJSONObject() & optJSONArray() methods to check if the underlying is an Object or Array. Below is an example for that.

JSONObject json = new JSONObject("{\"key1\": \"val1\",\n" + 
        " \"key2\": {\"level2\": {\"level3\": \"val3\"}}\n" + 
        "}");

JSONObject json1 = new JSONObject("{\"key1\": \"val1\",\n" + 
        " \"key2\": {\"level2\": [{\"level3\": \"val3\"}]}\n" + 
        "}");

if(json.getJSONObject("key2").optJSONObject("level2") != null) {
    System.out.println("json : it is a jsonobject");
}
else if(json.getJSONObject("key2").optJSONArray("level2") != null) {
    System.out.println("json : it is a jsonarray");
}


if(json1.getJSONObject("key2").optJSONObject("level2") != null) {
    System.out.println("json1 : it is a jsonobject");
}
else if(json1.getJSONObject("key2").optJSONArray("level2") != null) {
    System.out.println("json1 : it is a jsonarray");
}
0
votes

Use 'jsonObj.get("level2)' and check whether the type is JsonArray and then try to cast it.

0
votes

If you're open to using Jackson's Databind module, it's pretty straightforward:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

// ...

// parse your JSON data into a JsonNode
JsonNode jsonObj = new ObjectMapper().readTree(yourJsonString);

// should really do some error checking here unless you're 100% sure
// you're always going to be getting "key2" and "level2" in your JSON
// data structure; look into Jackson's "hasNonNull()" function
JsonNode level2 = jsonObj.get("key2").get("level2");

if (level2.isArray()) {
    ArrayNode level2arr = (ArrayNode)level2;
    // ... do something with level2arr as an array
    // ...
} else if (level2.isObject()) {
    // ... use it as an object node
    // ...
}
0
votes

I would stringify the JSON object and check the index of '{' or '['.

Given a Json, I would stringify it. And if the index of '{' is 0 in the stringified object then its a Json Object and if the index of '[' is 0 in the stringified object then its a Json Array.

I use Vertx framework and I can verify them as follows:

JsonObject jsonObject = new JsonObject().put("name", "avishek");
JsonArray jsonArray = new JsonArray().add("Vizury").add("MediaIQ");

System.out.println(jsonObject.toString().indexOf("{") == 0); //Json Object
System.out.println(jsonArray.toString().indexOf("[") == 0); //Json Array