I have a JSON which has many arrays with a different name, just like below JSON.
{
"CA": [
{
"high": 5,
"low": 3,
"key": "ABPS"
},
{
"high": 6,
"low": 2,
"key": "ABPO"
}
],
"EE": [
{
"high": 8,
"low": 4,
"key": "ABPS"
},
{
"high": 7,
"low": 2,
"key": "ABPO"
}
]
}
I am trying to iterate JSON array values dynamically without specifying the name of the array.
I am able to read array with specifying the name of the array with below code but how to read array values dynamically without specifying the name of every array because the JSON file I have it has thousands of array.
package com.abc;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class JsonRead {
private static final String filePath = "jsonTestFile.json";
public static void main(String[] args) {
try (FileReader reader = new FileReader(ClassLoader.getSystemResource(filePath).getFile())) {
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(reader);
// get an array from the JSON object
JSONArray lang = (JSONArray) jsonObject.get("CA");
Iterator i = lang.iterator();
// take each value from the json array separately
while (i.hasNext()) {
JSONObject innerObj = (JSONObject) i.next();
System.out.println("high " + innerObj.get("high") + " low " + innerObj.get("low")+ " key " + innerObj.get("key"));
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
This might help
for (Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
JSONArray jArray = (JSONArray) jsonObject.get(key);
}
Related
I have a json String like below and I want to split/explode it in to multiple json string.
input:
{
"name": "paddy",
"age": 29,
"cities": [
{
"cityName": "Chennai",
"year": "2013-2015"
},
{
"cityName": "Bangalore",
"year": "2015-2019"
}
]
}
And I want to convert in to two Json string
json 1
{
"name": "paddy",
"age": 29,
"cities": [
{
"cityName": "Chennai",
"year": "2013-2015"
}
]
}
json 2
{
"name": "paddy",
"age": 29,
"cities": [
{
"cityName": "Bangalore",
"year": "2015-2019"
}
]
}
As of now, my approach below using jackson library.
package com.test;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class JsonParser {
public static void main(String[] args) throws IOException {
String json =
"{\n"
+ "\t\"name\": \"paddy\",\n"
+ "\t\"age\": 29,\n"
+ "\t\"cities\": [\n"
+ "\t\t{\n"
+ "\t\t\t\"cityName\": \"Chennai\",\n"
+ "\t\t\t\"year\": \"2013-2015\"\n"
+ "\t\t},\n"
+ "\t\t{\n"
+ "\t\t\t\"cityName\": \"Bangalore\",\n"
+ "\t\t\t\"year\": \"2015-2019\"\n"
+ "\t\t}\n"
+ "\t]\n"
+ "}";
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// Create a list to store the result (the list will store Jackson tree model objects)
List<JsonNode> result = new ArrayList<>();
JsonNode tree = mapper.readTree(json);
JsonNode paths = tree.get("cities");
Iterator<JsonNode> elements = paths.elements();
while (elements.hasNext()) {
JsonNode path = elements.next();
// Create a copy of the tree
JsonNode copyOfTree = mapper.valueToTree(tree);
((ArrayNode)copyOfTree.get("cities")).removeAll().add(path);
// Add the modified tree to the result list
result.add(copyOfTree);
}
// Print the result
for (JsonNode node : result) {
System.out.println(mapper.writeValueAsString(node));
System.out.println();
}
}
}
This above approach can work fine if the json is smaller. Is there any better approach to handle large json files. For example, assume the "cities" have million objects.
Thanks.
There is many different factors you need to consider. First, do not copy the whole root object. In case, you have a big cities array you just waste a memory for creating new copy and remove all elements from it. See below example:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.File;
import java.io.IOException;
public class JsonApp {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./spring-basics/src/main/resources/test.json");
ObjectMapper mapper = new ObjectMapper();
// read whole JSON
ObjectNode root = (ObjectNode) mapper.readTree(jsonFile);
String citiesFieldName = "cities";
// remove cities from root, now it contains only common properties
ArrayNode cities = (ArrayNode) root.remove(citiesFieldName);
cities.elements().forEachRemaining(item -> {
// copy root
ObjectNode copyOfRoot = root.deepCopy();
// add one city to copy
copyOfRoot.set(citiesFieldName, copyOfRoot.arrayNode().add(item));
// add to result or send further
System.out.println(copyOfRoot);
});
}
}
Above code copies root and adds one element to cities array. Now, we need to think what to do with result. You can send it immediately for next processing or store in list and send it in bulk operation. Another improvement could be splitting cities arrays on bigger chunks, more than 1 element. See this article, how to split list. For example, in case you have 1_000_000 elements, split it on list of 1_000 elements chunks.
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader("C:/Users/dan/Documents/rental.txt"));
JSONObject jsonObject = (JSONObject) obj;
for(Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(jsonObject.get(key));
}
} catch (Exception e) {
e.printStackTrace();
}
Following is the JSON String:
{
"Search": {
"VehicleList": [
{
"sipp": "CDMR",
"name": "Ford Focus",
"price": 157.85,
"supplier": "Hertz",
"rating": 8.9
},
{
"sipp": "FVAR",
"name": "Ford Galaxy",
"price": 706.89,
"supplier": "Hertz",
"rating": 8.9
}
]
}
}
}
Hi, I can iterate over the whole JSON object with my code but right now I want to print out the name of a vehicle and the price of the vehicle individually. Any help would be appreciated, I am a beginner when it comes to working with JSON.
Your JSON is structured like this JsonObject -> JsonArray-> [JsonObject]
With that in mind you can access the name and price with this
Object obj = parser.parse(new FileReader("C:/Users/dan/Documents/rental.txt"));
JSONArray jsonArray = (JSONObject) obj.getJsonArray("VehicleList");
for(JSONObject jsonObject : jsonArray){
System.out.println(jsonObject.getString("name") + " " + jsonObject.getDouble("price"))
}
}
Depending on your import library it may deviate from the above but the concept is the same.
You need to iterate over the json. For example.
$.Search.VehicleList[0].price will give you [157.85]
$.Search.VehicleList[1].price will give you [706.89]
http://www.jsonquerytool.com/ will come handy for you :)
I am currently studying newick format. https://en.wikipedia.org/wiki/Newick_format.
I have a newick string of a tree
(ABC,(STU,VWX)DEF,(GHI,JKL)MNO)PQR;
How to convert this string into a hierarchical JSON object like
JSONObject tree = {
name: 'PQR',
children: [{
name: 'ABC'
}, {
name: 'DEF',
children: [{
name: 'STU'
}, {
name: 'VWX'
}]
}, {
name: 'MNO',
children: [{
name: 'GHI'
}, {
name: 'JKL'
}]
}]
}
This is what i have tried but could not think further of how to fill the children of root node
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class Series1 {
public static void main(String[] args) throws JSONException
{
String data="(ABC,(STU,VWX,EFG)DEF,YZA,HIJ,(GHI,JKL)MNO,BCD)PQR";
JSONObject tree=new JSONObject();
tree.put("name",data.substring(data.lastIndexOf(")")+1,data.length()));
tree.put("children", getChildren(data.substring(1,data.lastIndexOf(")"))));
}
public static JSONArray getChildren(String children) throws JSONException
{
JSONArray childrenArray=new JSONArray();
List<Integer> commaIndexList=new ArrayList<Integer>();
List<String> childrenStringList=new ArrayList<String>();
for (int index = children.indexOf(",");index >= 0;index = children.indexOf(",", index + 1))
{
if(children.substring(index+1, index+2).equalsIgnoreCase("("))
{
commaIndexList.add(index);
System.out.println(index);
}
}
childrenStringList.add(children.substring(0, commaIndexList.get(0)));
childrenStringList.add(children.substring(commaIndexList.get(commaIndexList.size()-1)+1));
for(int i=0;i<commaIndexList.size()-1;i++)
{
childrenStringList.add(children.substring(commaIndexList.get(i)+1, commaIndexList.get(i+1)));
}
for(String childrenString:childrenStringList)
{
JSONObject childObject=new JSONObject();
if(childrenString.lastIndexOf(")")>0)
{
childObject.put("name", childrenString.substring(childrenString.lastIndexOf(")")+1));
childObject.put("children", getChildren(childrenString.substring(childrenString.indexOf("(")+1,childrenString.lastIndexOf(")"))));
}
else
{
childObject.put("name",childrenString);
}
childrenArray.put(childObject);
}
return childrenArray;
}
}
I'd say this problem is similar to evaluating math expressions, e.g. 2+5*(10-3)=?
+
2 *
5 -
10 3
The key is to use stack operations to remake the 'inorder' tree structure into 'postorder' which is in this case 2 5 10 3 - * +
This is a definite form without parentheses and so easily readable for machine processing. If you are interested, i can have a look at it.
I am trying to read the following JSON file in java.
Here is my JSON File
{
"names": [
{
"no": 1,
"name": "John"
},
{
"no": 2,
"name": "Paul"
}
],
"new_names": [
{
"no": 11,
"name": "John"
},
{
"no": 12,
"name": "Paul"
}
]
}
Java Code:
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class ReadFile {
#SuppressWarnings("unchecked")
public static void main(String[] args) {
JSONParser parser = new JSONParser();
try {
Object obj = parser.parse(new FileReader(
"D://data.json"));
JSONObject jsonObject = (JSONObject) obj;
JSONArray nameList = (JSONArray) jsonObject.get("names");
System.out.println("\nnames:");
Iterator<String> iterator = nameList.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I want to print names array, but I am getting following error:
java.lang.ClassCastException: org.json.simple.JSONObject cannot be
cast to java.lang.String at ReadFile.main(ReadFile.java:34)
Your JSonArray nameList has has JSONObjects inside, not the strings,
You should do replace your String with JSONObject as mentioned in Exception trace
Iterator<JSONObject > iterator = nameList.iterator();
while (iterator.hasNext()) {
JSONObject jsonObjct= iterator.next()
System.out.println(jsonObjct.getInt("no"));
System.out.println(jsonObjct.getString("name"));
}
Iteratoring from JsonObject..
So you should change below:
Iterator<String> iterator = nameList.iterator();
to following:
Iterator<JSONObject> iterator = nameList.iterator();
And iterate it using for loop, Iterator won't work for JSONArray.
It is this line that is causing the problem:
Iterator<String> iterator = nameList.iterator();
Try using the following instead:
arrLength = nameList.Length()
for (int i = 0; i < arrLength; ++i) {
JSONObject jsonObj = nameList.getJSONObject(i);
System.out.println(jsonObj)
}
I need to read JsonElements from given JSON files. I am using org.json.simple jar.
Here is the sample of my json:
[{
"Submission ID": "9938306",
"Lat": "17.447191666666665",
"Long": "78.38849"
},
{
"Submission ID": "9938306",
"Lat": "17.447191666666665",
"Long": "78.38849"
}]
I wrote this following code to read JsonArray but not able to figure out how to read JsonElements from it:
try {
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("sampleData.json"));
JSONArray array = (JSONArray) obj;
Iterator iter = array.iterator();
while (iter.hasNext()){
}
}
How can I read all JSONelements for each JSONarray? For example:
EDIT
I want to iterate all JsonElements in JsonAray. In my given Json I do have submission ID and submission_ID. Key is dynamic in some point and I need to read it and want to apply some regex on it.
running code. try it
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
public class Test {
public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("/home/stpl/NIKHIL/text.json"));
JSONArray array = (JSONArray) obj;
for(int i = 0; i < array.size(); i++)
{
JSONObject objects = (JSONObject)array.get(i);
System.out.println(objects.get("Submission ID")+" "+objects.get("Lat")+" "+objects.get("Long"));
}
}
}
my text.json
[{
"Submission ID": "9938306",
"Lat": "17.447191666666665",
"Long": "78.38849"
},
{
"Submission ID": "9938306",
"Lat": "17.447191666666665",
"Long": "78.38849"
}]
You should use Jackson ? Which provides good utilities to parse JSON file.
You can try this code :
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("d://sample.json"));
JSONArray array = (JSONArray) obj;
Iterator iter = array.iterator();
while (iter.hasNext()) {
JSONObject json = (JSONObject) iter.next();
Iterator<String> keys = json.keySet().iterator();
while (keys.hasNext()) {
String key = keys.next();
System.out.println("Key :" + key + " Value :" + json.get(key));
}
}
This will iterate each key and value of given JSON.
Please try following code,
try {
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("sampleData.json"));
JSONArray array = (JSONArray) obj;
for(int i=0;i<array.length();i++){
JSONObject obj=array.getJSONObject(i);
System.out.println(obj.get("Long"));
}
}
Note:not compiled