Access first array in a JSON string using JSON Parser - java

How do I access the array products from the below JSON string? I would ideally do this, and it works -
JSONParser parser = new JSONParser();
Object response = parser.parse(json);
JSONObject jsonObject = (JSONObject) response;
JSONObject info = (JSONObject) jsonObject.get("info");
JSONArray data = (JSONArray) jsonObject.get("products");
But the problem is the root element info is not always the same, so I can't hardcode my code. Basically, I don't want to access products by accessing info first. I want to directly access the products array.
How can I do this?
{
"info": {
"products": [
{
"test": 11577,
"number": 2541,
"product": "deoderant",
"id": 1,
"subId": 5,
"tempId": 3,
"name": null,
"lastModified": "2015-05-24",
"lastUsed": 5,
"score": 0.93,
"season": "Seasonal",
"availability": 0,
"itemRanking": null,
"itemQuantity": 5,
"listOfStores": [
7896
]
}
],
"storeId": 10145678
}
}

convert to map, LinkedHashMap or HashMap as per your need, then get the entry value.
public class Test {
public static void main(String[] args) {
String json = "{\"info\": {\"products\": [{\"test\": 11577,\"number\": 2541,\"product\": \"deoderant\",\"id\": 1,\"subId\": 5,\"tempId\": 3,\"name\": null,\"lastModified\": \"2015-05-24\",\"lastUsed\": 5,\"score\": 0.93,\"season\": \"Seasonal\",\"availability\": 0,\"itemRanking\": null,\"itemQuantity\": 5,\"listOfStores\": [7896]}],\"storeId\": 10145678}}";
JSONObject jsonObject;
try {
jsonObject = new JSONObject(json);
Map<String, Object> map = getMap(jsonObject);
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey());
System.out.println(entry.getValue());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static Map getMap(JSONObject object) {
Map<String, Object> map = new LinkedHashMap<String, Object>();
Object jsonObject = null;
String key = null;
Object value = null;
try {
Iterator<String> keys = object.keys();
while (keys.hasNext()) {
key = null;
value = null;
key = keys.next();
if (null != key && !object.isNull(key)) {
value = object.get(key);
}
if (value instanceof JSONObject) {
map.put(key, getMap((JSONObject) value));
continue;
}
if (value instanceof JSONArray) {
JSONArray array = ((JSONArray) value);
List list = new ArrayList();
for (int i = 0 ; i < array.length() ; i++) {
jsonObject = array.get(i);
if (jsonObject instanceof JSONObject) {
list.add(getMap((JSONObject) jsonObject));
} else {
list.add(jsonObject);
}
}
map.put(key, list);
continue;
}
map.put(key, value);
}
} catch (Exception e) {
System.out.println(e);
}
return map;
}
}
Output
info
{products=[{test=11577, number=2541, product=deoderant, id=1, subId=5, tempId=3, name=null, lastModified=2015-05-24, lastUsed=5, score=0.93, season=Seasonal, availability=0, itemRanking=null, itemQuantity=5, listOfStores=[7896]}], storeId=10145678}

I don't know if this is the best way - but you can always get the keys of your objects with the keys() method. So you will know the name of the top object.

Use fasterxml lib,you can write code like below:
ObjectMapper mapper = new ObjectMapper();
// json is your json string
String json = "";
JsonNode jsonNode = node.findParent("products").get("products");
System.out.println(jsonNode);

Related

Read hashmap nested properties dynamically

I have the JSON below:
"total":"2",
"offset":"1",
"limit":"2",
"results":[{
"code":1,
"title":"RESTAURANTE SADOCHE",
"contact":{
"code":10,
"name":"HENRIQUE BARBALHO",
"company":{
"code":100,
"name":"RESTAURANTE SADOCHE LTDA-ME"
}
}
},
{
"code":2,
"title":"ARNALDO GRILL",
"contact":{
"code":20,
"name":"FÁTIMA COSTA",
"company":{
"code":200,
"name":"COSTA NATAL RESTAURANTE EIRELI"
}
}
}]
I turned this JSON into a Java HashMap using the Gson library.
Map<String, Object> retMap = new Gson().fromJson(jsonUpString, new TypeToken<HashMap<String, Object>>(){}.getType());
I need to dynamically read some properties of this created hashmap. Ex: title, name of contact and name of company.
Sometimes these properties (title, name of contact and name of company) can be inside lists.
Below my code:
String propertyName = "name";
String nesting = "results;contact;company";
String[] levels = nesting.split(";");
Map map = new HashMap();
map = retMap;
for (int i = 0; i < niveis.length; i++) {
map = (Map)map.get(levels[i]);
System.out.println(map);
if (i == levels.length - 1) {
System.out.println(map.get(propertyName));
}
}
But if the properties (results, contact or company) return more than one object, the JSON returns them as lists, and I can't get the information I need.
I solved the problem using...
private static void leJSON(Object object) {
if (object instanceof JSONObject) {
Set < String > ks = ((JSONObject) object).keySet();
for (String key: ks) {
Object value = ((JSONObject) object).get(key);
if (value != null) {
System.out.printf("%s=%s (%s)\n", key, value, value.getClass().getSimpleName());
if (value.getClass().getSimpleName().equalsIgnoreCase("JSONArray")) {
JSONArray ja = (JSONArray) value;
for (int i = 0; i < ja.size(); i++) {
leJSON(ja.get(i));
}
}
if (value.getClass().getSimpleName().equalsIgnoreCase("JSONObject")) {
leJSON(value);
}
}
}
}
}
main method...
String json = "{...}";
JSONObject object = (JSONObject) JSONValue.parse(jsonString2);
readJSON(object);

How to remove empty json object in jsonarray

JSONObject sss = arr_cat_details_old.getJSONObject(0).getJSONArray("pac_selected").getJSONObject(1);
sss.remove("pack_selected_id");
"pac_selected": [{
"pack_selected_id": "7"
}, {}, {
"pack_selected_id": 45
}]
assuming:
String jsonString = "pac_selected": [{
"pack_selected_id": "7"
}, {}, {
"pack_selected_id": 45
}]
I would do the following, based on this answer:
JSONArray list = new JSONArray();
JSONArray jsonArray = new JSONArray(jsonstring);
int len = jsonArray.length();
if (jsonArray != null) {
for (int i=0;i<len;i++)
{
String element = jsonArray.get(i);
if (!element.isEmpty())
{
list.put(element);
}
}
}
Then just use list instead of jsonArray.
Try this method
String json = .... // your json
Type type = new TypeToken<Map<String, Object>>() {}.getType();
Map<String, Object> data = new Gson().fromJson(json, type);
for (Iterator<Map.Entry<String, Object>> it = data.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Object> entry = it.next();
if (entry.getValue() == null) {
it.remove();
} else if (entry.getValue().getClass().equals(ArrayList.class)) {
if (((ArrayList<?>) entry.getValue()).size() == 0) {
it.remove();
}
}
}
String json1 = new GsonBuilder().setPrettyPrinting().create().toJson(data);
System.out.println("Latest json "+json1);
Add this to pom.xml
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>

How to get keys in nested json with parent prefix using GSON in java

I have tried the following example.
public static void operate2(JsonElement jsonElement, List keys, JsonElement jsonElement2, String prefix){
String prefixnew = "";
if(jsonElement.isJsonArray()){
JsonArray jsonArray = jsonElement.getAsJsonArray();
for(int i=0; i<jsonArray.size(); i++){
jsonElement = jsonArray.get(i);
operate2(jsonElement, keys, jsonElement2, prefix);
}
}else if(jsonElement.isJsonObject()){
JsonObject jsonObject = jsonElement.getAsJsonObject();
Set<Map.Entry<String,JsonElement>> childEntrySet = jsonObject.entrySet();
for (Map.Entry<String, JsonElement> child: childEntrySet) {
jsonElement2 = child.getValue();
Object keyCheck = new Gson().fromJson(jsonElement2.toString(), Object.class);
if (keyCheck instanceof Map) {
prefix += child.getKey()+"_";
keys.add(prefix);
System.out.println("Map="+child.getKey());
}else if (keyCheck instanceof Collection) {
if(!prefix.equals("")){
prefix += child.getKey()+"_";
keys.add(prefix);
}else{
prefix = child.getKey()+"_";
keys.add(prefix);
}
System.out.println("Collection="+child.getKey());
}else{
prefix += "";
}
operate2(jsonElement2, keys, jsonElement2, prefix);
}
}else{
prefix = "";
}
}
public static void test2(String json){
JsonElement jsonElement = new JsonParser().parse(json);
JsonElement jsonElement2 = null;
String prefix = "";
List keys = new ArrayList();
operate2(jsonElement, keys, jsonElement2, prefix);
Set keySet = new HashSet(keys);
System.out.println("Keys = "+keys);
}
The output I got Keys = [items_, items_contact_, items_contact_records_, items_contact_records_recordings_, items_contact2_]
But I need items_, items_contact_, items_records_ .... As we can see that record is not the child of the contact, so items_contact_records_ should not be there. Instead items_records_ should be.
The source json would be
{
"items": [{
"id": 633706061003,
"fromNumber": "16572307534",
"contact": {
"id": 499354453003,
"homePhone": "16572307534"
},
"records": [{
"id": 353389055003,
"result": "LA",
"recordings": [{
"id": 16427622003
}]
}]
}],
"limit": 100,
"offset": 0,
"totalCount": 5949
}
I would use the following approach:
if the root element is not a json object, return an empty list
otherwise iterate other its entries, and for each one add the key if the value associated with is either an object or an array
proceed recursively for the value
public static List<String> operate(final JsonElement jsonElement, final String prefix, final boolean firstLayer) {
if(jsonElement.isJsonObject() || (!firstLayer && jsonElement.isJsonArray())) {
List<String> keys = new ArrayList<>();
if(jsonElement.isJsonObject()) {
JsonObject jObj = jsonElement.getAsJsonObject();
for(Map.Entry<String, JsonElement> entry : jObj.entrySet()) {
JsonElement value = entry.getValue();
String newPrefix = prefix + entry.getKey();
if(value.isJsonArray() || value.isJsonObject()) {
keys.add(newPrefix);
keys.addAll(operate(value, newPrefix + "_", false));
}
}
} else {
JsonArray array = jsonElement.getAsJsonArray();
for(JsonElement element : array) {
keys.addAll(operate(element, prefix, false));
}
}
return keys;
} else {
return Collections.emptyList();
}
}
and the test method:
public static void test(String json) {
JsonElement jsonElement = new JsonParser().parse(json);
List<String> keys = operate(jsonElement, "", true);
System.out.println("Keys = " + keys);
}
Running it on your example, you'll get:
Keys = [items, items_contact, items_records, items_records_recordings]

Array inside JSONArray iteration in java

My Json is:
{
"Response": {
"Asset": [
{
"id": 2461,
"name": "TestAsset7771",
"model_name": "TestModel777",
"serial_number": "TestAsset7771",
"current_data": {
"timestamp": "",
"name": "Temperature",
"value": "?"
}
},
{
"id": 2448,
"model_id": 1229,
"name": "TestAsset777",
"model_name": "TestModel777",
"serial_number": "TestAsset777",
"current_data": {
"timestamp": "",
"name": "Temperature",
"value": "?"
}
}
]
}
}
My code is:
JSONObject outerObject = new JSONObject(jsonObj.toString());
JSONObject innerObject = outerObject.getJSONObject("Response");
JSONArray jsonArray = innerObject.getJSONArray("Asset");
for (int i = 0, size = jsonArray.length(); i < size; i++)
{
JSONObject objectInArray = jsonArray.getJSONObject(i);
String[] elementNames = JSONObject.getNames(objectInArray)
for (String elementName : elementNames)
{
String value = objectInArray.getString(elementName);
System.out.printf("name=%s, value=%s\n", elementName, value);
}
}
For inner array - ie current data, am getting values as:
name=current_data,
value={"timestamp":"","name":"Temperature","value":"?"}
How can i put another inner array so that i can get values of
"timestamp":"", "name":"Temperature", "value":"?" in separate variables instead of complete JSON
Its better to use Gson to parse JSON. Anyway, if you decide to follow as this is, try as :
You have a class like this:
class CurrentData{
String name,timestamp,value;
void print(){
System.out.printf("name=%s, timestamp=%s, value=%s\n", name,timestamp, value);
}
}
Now, change your for loop as follows:
for (String elementName : elementNames)
{
if(!elementName.equals("current_data")){
String value = objectInArray.getString(elementName);
System.out.printf("name=%s, value=%s\n", elementName, value);
}
else{
CurrentData obj=new CurrentData();// You can use array of objects declaring outside the loop as your need
JSONObject curr_object=objectInArray.getJSONObject("current_data");
obj.name=curr_object.getString("name");
obj.timestamp=curr_object.getString("timestamp");
obj.value=curr_object.getString("value");
obj.print();
}
}
for (String elementName : elementNames)
{
JSONObject jsonobject = jsonarray.getJSONObject(elementName);
System.out.printf( "name=%s, value=%s\n",jsonobject.getString("name"),jsonobject.getString("value"));
}
"value" is another jason object, so you can just call "getJasonObject()" to obtain the item and then proceed with that new array as normal.
Edit: I made a fail (not enough C0FFEE in my memory) and corrected thanks to the comment.
JSONObject outerObject = new JSONObject(jsonObj.toString());
JSONObject innerObject = outerObject.getJSONObject("Response");
JSONArray jsonArray = innerObject.getJSONArray("Asset");
for (int i = 0, size = jsonArray.length(); i < size; i++) {
JSONObject objectInArray = jsonArray.getJSONObject(i);
JSONObject currentData = objectInArray.getJSONObject("current_data");
if (currentData != null) {
String timestamp = currentData.getString("timestamp");
String name = currentData.getString("name");
String value = currentData.getString("value");
// Assign above results to array elements or whatever
}
}
//nested jsonarray
FileReader inp=new FileReader("xyz.json");
JSONParser parser=new JSONParser();
Object obj=parser.parse(inp);
JSONArray jsonArray=(JSONArray) obj;
int len=jsonArray.size();
for(i:len)
{
JSONArray json1=(JSONArray) jsonArray.get(i);
Iterato iterator=json1.iterator();
while(iterator.hasNext())
System.out.println(iterator.next());
}

Update elements in a JSONObject

Lets say I gave a JSONObject
{
"person":{"name":"Sam", "surname":"ngonma"},
"car":{"make":"toyota", "model":"yaris"}
}
How do I update some of the values in the JSONObject?
Like below :
String name = jsonArray.getJSONObject(0).getJSONObject("person").getString("name");
name = "Sammie";
Use the put method: https://developer.android.com/reference/org/json/JSONObject.html
JSONObject person = jsonArray.getJSONObject(0).getJSONObject("person");
person.put("name", "Sammie");
Remove key and then add again the modified key, value pair as shown below :
JSONObject js = new JSONObject();
js.put("name", "rai");
js.remove("name");
js.put("name", "abc");
I haven't used your example; but conceptually its same.
Hello I can suggest you universal method. use recursion.
public static JSONObject function(JSONObject obj, String keyMain,String valueMain, String newValue) throws Exception {
// We need to know keys of Jsonobject
JSONObject json = new JSONObject()
Iterator iterator = obj.keys();
String key = null;
while (iterator.hasNext()) {
key = (String) iterator.next();
// if object is just string we change value in key
if ((obj.optJSONArray(key)==null) && (obj.optJSONObject(key)==null)) {
if ((key.equals(keyMain)) && (obj.get(key).toString().equals(valueMain))) {
// put new value
obj.put(key, newValue);
return obj;
}
}
// if it's jsonobject
if (obj.optJSONObject(key) != null) {
function(obj.getJSONObject(key), keyMain, valueMain, newValue);
}
// if it's jsonarray
if (obj.optJSONArray(key) != null) {
JSONArray jArray = obj.getJSONArray(key);
for (int i=0;i<jArray.length();i++) {
function(jArray.getJSONObject(i), keyMain, valueMain, newValue);
}
}
}
return obj;
}
It should work. If you have questions, go ahead.. I'm ready.
Generic way to update the any JSONObjet with new values.
private static void updateJsonValues(JsonObject jsonObj) {
for (Map.Entry<String, JsonElement> entry : jsonObj.entrySet()) {
JsonElement element = entry.getValue();
if (element.isJsonArray()) {
parseJsonArray(element.getAsJsonArray());
} else if (element.isJsonObject()) {
updateJsonValues(element.getAsJsonObject());
} else if (element.isJsonPrimitive()) {
jsonObj.addProperty(entry.getKey(), "<provide new value>");
}
}
}
private static void parseJsonArray(JsonArray asJsonArray) {
for (int index = 0; index < asJsonArray.size(); index++) {
JsonElement element = asJsonArray.get(index);
if (element.isJsonArray()) {
parseJsonArray(element.getAsJsonArray());
} else if (element.isJsonObject()) {
updateJsonValues(element.getAsJsonObject());
}
}
}
public static JSONObject updateJson(JSONObject obj, String keyString, String newValue) throws Exception {
JSONObject json = new JSONObject();
// get the keys of json object
Iterator iterator = obj.keys();
String key = null;
while (iterator.hasNext()) {
key = (String) iterator.next();
// if the key is a string, then update the value
if ((obj.optJSONArray(key) == null) && (obj.optJSONObject(key) == null)) {
if ((key.equals(keyString))) {
// put new value
obj.put(key, newValue);
return obj;
}
}
// if it's jsonobject
if (obj.optJSONObject(key) != null) {
updateJson(obj.getJSONObject(key), keyString, newValue);
}
// if it's jsonarray
if (obj.optJSONArray(key) != null) {
JSONArray jArray = obj.getJSONArray(key);
for (int i = 0; i < jArray.length(); i++) {
updateJson(jArray.getJSONObject(i), keyString, newValue);
}
}
}
return obj;
}
Recursive way to update value in depth in Kotlin
Example: setJsonValue("obj1/obj2/keyToUpdate", "new value")
fun setJsonValue(path: String, value: Any?) {
setJsonValueRec(
path = path.split("/"),
index = 0,
obj = jsonObj,
value = value
)
}
private fun setJsonValueRec(path: List<String>, index: Int, obj: JSONObject, value: Any?): JSONObject {
return obj.put(
path[index],
when (index) {
path.lastIndex -> value
else -> setJsonValueRec(
path = path,
index = index + 1,
obj = obj.getJSONObject(path[index]),
value = value
)
}
)
}

Categories

Resources