Dynamic parsing JSON to Java - java

I have problem with parsing JSON to Java. I have JSON code like that:
{
"Person 1": {
"name": "Jan",
"secname": "Kowalski",
"neighbours": {
"Person 2": {
"name": "Pawel",
"subname": "Nowak"
},
"Person 3": {
"name": "Ewa",
"subname": "Drzyzga"
}
},
"additionalInformation": {
"age": "38l",
"weight": "90kg"
}
}
}
I have only one Person in a head. He has got name, sec, name, neighbours and additionalInformation. He has 0 or more neigbours, I don't know how many. The same is with additionalInformation. With neighbours is simply because I know that every Person has only name and subname.
So I'm reading neighbours like that:
String head = "Person 1";
JSONObject obj = new JSONObject(jsonString);
Iterator iterator1 = obj.getJSONObject(head).keys();
while (iterator1.hasNext()) {
String key = (String) iterator1.next();
if (key.equals("neighbours")) {
Iterator iterator2 = obj.getJSONObject(head).getJSONObject(key).keys();
while (iterator2.hasNext()) {
String person = (String) iterator2.next();
System.out.println(obj.getJSONObject(head).getJSONObject(key).getJSONObject(person).getString("name"));
System.out.println(obj.getJSONObject(head).getJSONObject(key).getJSONObject(person).getString("subname"));
}
}
}
head can be dynamic, Person 1,2,3... but its not a problem. Problem is with recursive in that json because I don't know how additionalInformation will look like. It can be:
"additionalInformation ": {
"parents": {
"fromDad": {
"nameM": "Genowefa",
"nameD": "Jan"
},
"fromMother": {
"nameM": "Krystyna",
"nameD": "Antoni"
}
},
"weight": "90kg"
}
Is that possible to read all information in "additionalInformation"?
I have to store data like nodes because if I use method:
MODIFY "Person 1" "additionalInformation" "parents" "fromDad" "nameM" "John"
"nameM" will be change.
Is that possible? Could you tell me something about that?

Related

Read the all value presents in Hashmap

I have define List of HashMap and reading the response of JSON API . Currently able to read only one value from the list and I want to read all the values.
List<HashMap<String,Object>> allids = response.jsonPath().getList("data");
HashMap<String,Object> firstid = allids.get(0);
Object a = firstid.get("country");
System.out.println(a);
JSON Response in PostMan
{
"response": {
"code": 200,
"status": "success",
"alert": [
{
"message": "Success",
"type": "success",
"skippable": 1
}
],
"from_cache": 0,
"is_data": 1
},
"data": [
{
"id": 6004,
"airport_name": "Adampur Airport",
"city": "Adampur",
"country": "India",
"iata": "AIP",
"icao": "VIAX",
"latitude": "31.4338",
"longitude": "75.758797",
"altitude": "775"
}
]
}
Just forEach on your List you will get Map and then get all your Object bu using get .
List<HashMap<String,Object>> allids = response.jsonPath().getList("data");
allids.forEach(elem->{
String country = (String) elem.get("country");
String city = (String) elem.get("city");
// and so on.
});
Judging from the context, you can iterate over the list and get the Map values
List<HashMap<String,Object>> allids = response.jsonPath().getList("data");
for(int i=0; i<allids.size(); i++){
HashMap<String,Object> firstid = allids.get(i);
String country = (String) firstid.get("country");
String city = (String) firstid.get("city");
String iata = (String) firstid.get("iata");
String altitude = (String) firstid.get("altitude");
//similarly get others
System.out.println(country);
}

get json data based on object name

May be it's a simple task for some one.
I've json like below.
{
"address": {
"state": "World",
"address": "infinite space, 000",
"city": "Android city",
"address2": {
"state": "World2",
"address": "infinite space2, 002",
"city": "Android city2",
"address3": {
"state": "World3",
"address": "infinite space3, 003",
"city": "Android city3"
}
}
},
"valid": {
"state": "World",
"address": "infinite space, 000",
"city": "Android city",
"valid2": {
"state": "World2",
"address": "infinite space2, 002",
"city": "Android city2",
"valid3": {
"state": "World3",
"address": "infinite space3, 003",
"city": "Android city3"
}
}
}
}
This is a sample structure. Some times may have many objects inside of one object. I know this is a bad format of JSON but i've to achieve my requirement by using this only :-(.
My requirement is: when we sending the object name like address3 or valid3 to a method as argument. My method have to return key and value of object (Which we passed as argument). Any one know, how to achieve this in Java?
You can parse the JSON and convert the result into a HashMap<String,String>
Here is sample code for this JSON object .
public HashMap<String,String> getKeyValuePairs(JSONObject json,String key){
HashMap<String,String> jsonHashList=new HashMap<String,String>();
JSONObject desiredJSON = json.get(key);
Iterator<?> keys = desiredJSON.keys();
while( keys.hasNext() ) {
String key2 = (String)keys.next();
if ( desiredJSON.get(key2) instanceof JSONObject ) {
String value = desiredJSON.get(key2);
jsonHashList.add(key2,value);
}
}
return jsonHashList;
}
Note : In this case key is assumed to be at level one of passed JSON so if you want to pass any JSON to get it's key values separated pass the Level One JSON.
This is the solution
private void parseJson(JSONObject jsonObject, String objName){
try {
for(int i = 0; i < jsonObject.length(); i++){
if(jsonObject.get(jsonObject.names().getString(i)) instanceof JSONObject){
JSONObject singleObj = new JSONObject(jsonObject.get(jsonObject.names().getString(i)).toString());
Iterator<String> keys= singleObj.keys();
while (keys.hasNext()){
String keyValue = keys.next();
final String valueString = singleObj.getString(keyValue);
if(!isJSONObjectOrString(valueString)){
if(keyValue.contains(objName) || valueString.contains(objName)
|| jsonObject.names().getString(i).contains(objName)){
Log.e("objectName", jsonObject.names().getString(i));
Log.e(keyValue, valueString);
}
}
}
parseJson(singleObj);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}

Json comparison which contains arrays using Java

Json1:
{
"array1": [
{
"Name": "Xytrex Co.",
"Description": "Industrial Cleaning Supply Company",
"Account Number": "ABC15797531",
"Address": {
"Street": "st.road",
"pin": "789723"
}
},
{
"Name": "XYZ Company",
"Address": {
"Street": "Peters road",
"pin": "789700"
}
}
]
}
Json2:
{
"array2":[
{
"Name": "Xytrex Co.",
"Description": "Industrial Cleaning Supply Company",
"Account Number": "ABC15797531",
"Address": {
"Street": "st.road",
"pin": "789723"
}
},
{
"Name": "XYZ Company",
"Description": "Domestic Cleaning Supply Company",
"Address": {
"Street": "Peters road",
"pin": "789700"
}
}
]
}
Java Code used by me:
JsonParser Parser = new JsonParser();
Object obj1 = Parser.parse(new
FileReader("/home/cloudera/Desktop/SampleJson/src/JSON1.json"));
Object obj2 = Parser.parse(new
FileReader("/home/cloudera/Desktop/SampleJson/src/JSON2.json"));
JsonObject jsonObject1 = (JsonObject) obj1;
JsonObject jsonObject2 = (JsonObject) obj2;
Set<Map.Entry<String, JsonElement>> entries1 = jsonObject1.entrySet();
Set<Map.Entry<String, JsonElement>> entries2 = jsonObject2.entrySet();
for (Map.Entry<String, JsonElement> entry : entries1) {
//System.out.println("FirstJson:"+entry.getKey());
}
for (Map.Entry<String, JsonElement> entry : entries2) {
//System.out.println("SecondJson:"+entry.getKey());
}
if (jsonObject1.equals(jsonObject2)) {
System.out.println("Success");
} else {
entries1.removeAll(entries2);
//System.out.println("\n");
System.out.println("Result:" + entries1);
}
I have to compare two json files which contain arrays using Java, In array1 "Description" is missing I have to print that exact key and not the entire Json from first to last. In my output also "Description" is not there, but it's not printing exactly that key, its printing from first to last. Please help me with this.
The output I got:
Result:[array1=[{"Name":"Xytrex Co.","Description":"Industrial Cleaning Supply Company","Account Number":"ABC15797531","Address":{"Street":"st.road","pin":"789723"}},{"Name":"XYZ Company","Address":{"Street":"Peters road","pin":"789700"}}]]
This library is clean way to handle json comparison. It also has compare mode like strict check etc.
http://jsonassert.skyscreamer.org/javadoc/org/skyscreamer/jsonassert/JSONCompare.html
For your usecase you can check JSONCompareResult solves your problem.
I'd suggest you to use https://github.com/eBay/json-comparison library.
This library based on JsonAssert project but provide additional features
such as 'Exclude paths' , dealing with order and more

Parsing inserted json object android

Sorry for my english. I try parsing inserted json, in my example i have this json:
{
"myTable": {
"1": {
"type": "1",
"category": "1",
"body": {
"2": {
"id": "2",
"device_name": "test 1"
},
"5": {
"id": "5",
"device_name": "test 2"
}
}
},
"2": {
"type": "2",
"category": "1",
"body": {
"6": {
"id": "6",
"device_name": "test 3"
}
}
}
}
}
Its json object to json object. This put me stumped. Bellow my try code parse this json
JSONObject sensorTypes = json.getJSONObject("myTable");
if(sensorTypes.length() > 0) {
Iterator<String> iterasensorTypes = sensorTypes.keys();
while(iterasensorTypes.hasNext()) {
String currentKey = iterasensorTypes.next();
JSONObject obj = sensorTypes.optJSONObject(currentKey);
if(obj != null) {
Log.e("type", obj.getString("type"));
Log.e("category", obj.getString("category"));
JSONObject sensor = json.getJSONObject("body");
if(sensor.length() > 0) {
Iterator<String> iteratorSensor = sensor.keys();
while( iteratorSensor.hasNext() ) {
String currentKeySensor = iteratorSensor.next();
JSONObject objSensor = sensor.optJSONObject(currentKeySensor);
if(objSensor != null) {
Log.e("device_name", objSensor.getString("device_name"));
}
}
}
}
}
}
And i have this:
org.json.JSONException: No value for body
UPD:
My log:
E/type﹕ 1
E/category﹕ 1
E/ get﹕ org.json.JSONException: No value for body
You are using json.getJSONObject("body"); instead of obj.getJSONObject("body");, json is the top object, the one with the key myTable. body is inside the children of myTable, the ones you iterate through and reference using the obj object JSONObject obj = sensorTypes.optJSONObject(currentKey);
Instead of
JSONObject sensor = json.getJSONObject("body");
use
JSONObject sensor = obj.getJSONObject("body"); //changed to obj from json

Parsing nested JSON

I have the following JSON:
{
"registration": {
"name": "Vik Kumar",
"first_name": "Vik",
"last_name": "Kumar",
"bloodGroup": "B-",
"gender": "male",
"birthday": "10\/31\/1983",
"email": "vik.ceo\u0040gmail.com",
"cellPhone": "1234123456",
"homePhone": "1234123457",
"officePhone": "1234123458",
"primaryAddress": "jdfjfgj",
"area": "jfdjdfj",
"location": {
"name": "Redwood Shores, California",
"id": 103107903062719
},
"subscribe": true,
"eyePledge": false,
"reference": "fgfgfgfg"
}
}
I am using the following code to parse it:
JsonNode json = new ObjectMapper().readTree(jsonString);
JsonNode registration_fields = json.get("registration");
Iterator<String> fieldNames = registration_fields.getFieldNames();
while(fieldNames.hasNext()){
String fieldName = fieldNames.next();
String fieldValue = registration_fields.get(fieldName).asText();
System.out.println(fieldName+" : "+fieldValue);
}
This works fine and it print all the values except for location which is kind of another level of nesting. I tried the same trick as above code to pass json.get("location") but that does not work. Please suggest how to make it work for location.
You need to detect when you are dealing with a (nested) Object using JsonNode#isObject:
public static void printAll(JsonNode node) {
Iterator<String> fieldNames = node.getFieldNames();
while(fieldNames.hasNext()){
String fieldName = fieldNames.next();
JsonNode fieldValue = node.get(fieldName);
if (fieldValue.isObject()) {
System.out.println(fieldName + " :");
printAll(fieldValue);
} else {
String value = fieldValue.asText();
System.out.println(fieldName + " : " + value);
}
}
}
Thus, when you reach an object, such as location, you'll call the printAll recursively to print all its inner values.
org.codehaus.jackson.JsonNode json = new ObjectMapper().readTree(jsonString);
org.codehaus.jackson.JsonNode registration_fields = json.get("registration");
printAll(registration_fields);
Since location is nested within registration, you need to use:
registration_fields.get("location");
to get it. But isn't it already processed by the while-loop, why do you need to get it separately?

Categories