Parsing JSON with Java from a dictionary api - java

Very new to JSON. Using json-lib for this and been pulling my hair out trying to get "definitions" from this JSON response by Oxford Dictionaries API. Tried all sorts of things. But can never get anything more specific than everything from "results". Would like to figure out why this is so difficult otherwise will just resort to regex.
JSONObject obj = new JSONObject(stringBuilder.toString());
JSONArray arr = obj.getJSONArray("results");
String test = arr.getJSONObject(1).toString(); // Empty wtf?
String definition = obj.getString("definitions"); // empty also...
Managed to also access "id", "language" and "lexicalEntries" separately, but anything beyond that doesn't seem to want to cooperate.... Is this a normal JSON response? It's quite awkward no? Thanks...
JSON:
{
"metadata": {
"provider": "Oxford University Press"
},
"results": [
{
"id": "ace",
"language": "en",
"lexicalEntries": [
{
"entries": [
{
"homographNumber": "000",
"senses": [
{
"definitions": [
"a playing card with a single spot on it, ranked as the highest card in its suit in most card games"
],
"id": "m_en_gbus0005680.006"
},
{
"definitions": [
"a person who excels at a particular sport or other activity"
],
"id": "m_en_gbus0005680.010",
"subsenses": [
{
"definitions": [
"a pilot who has shot down many enemy aircraft"
],
"id": "m_en_gbus0005680.011"
}
]
},
{
"definitions": [
"(in tennis and similar games) a service that an opponent is unable to return and thus wins a point"
],
"id": "m_en_gbus0005680.013",
"subsenses": [
{
"definitions": [
"a hole in one"
],
"id": "m_en_gbus0005680.014"
}
]
}
]
}
],
"language": "en",
"lexicalCategory": "Noun",
"text": "ace"
},
{
"entries": [
{
"homographNumber": "001",
"senses": [
{
"definitions": [
"very good"
],
"id": "m_en_gbus0005680.016"
}
]
}
],
"language": "en",
"lexicalCategory": "Adjective",
"text": "ace"
},
{
"entries": [
{
"homographNumber": "002",
"senses": [
{
"definitions": [
"(in tennis and similar games) serve an ace against (an opponent)"
],
"id": "m_en_gbus0005680.020",
"subsenses": [
{
"definitions": [
"score an ace on (a hole) or with (a shot)"
],
"id": "m_en_gbus0005680.026"
}
]
},
{
"definitions": [
"achieve high marks in (a test or exam)"
],
"id": "m_en_gbus0005680.028",
"subsenses": [
{
"definitions": [
"outdo someone in a competitive situation"
],
"id": "m_en_gbus0005680.029"
}
]
}
]
}
],
"language": "en",
"lexicalCategory": "Verb",
"text": "ace"
}
],
"type": "headword",
"word": "ace"
}
]
}

String jsonData = sb.toString();
JSONObject obj = new JSONObject(jsonData);
JSONArray resultsArr = obj.getJSONArray("results");
String test = resultsArr.getJSONObject(0).toString();
JSONArray lexicalEntriesArr = resultsArr.getJSONObject(0).getJSONArray("lexicalEntries");
JSONArray entriesArr = lexicalEntriesArr.getJSONObject(0).getJSONArray("entries");
JSONArray sensesArr = entriesArr.getJSONObject(0).getJSONArray("senses");
JSONArray definitionsArr = sensesArr.getJSONObject(0).getJSONArray("definitions");
String definition = definitionsArr.toString();
Reference: http://jsonviewer.stack.hu/
Watch carefully the way we traverse the JSON object and when we should use getJSONObject & getJSONArray methods to retrieve the particular type of data we want from JSON Object.
Update: You might want to iterate the JSON array as per your requirement. I have just explained the case as in how to reach till definitions.

Related

Filter nested json data using jsonpath as in example

I am using jsonpath to filter.
Json(Dummy json just to explain) source String, which is basically a list of Operating systems and details of its programs etc. In this example, the OS whose id = 1403 is a windows 10 OS and has 2 features acchritecture and browser. There are more details to the browser feature as shown in json
[
{
"id": 1403,
"os": "window 10",
"features": [
{
"id": 1356,
"name": "architecture",
"value": [
{
"id": 1308,
"feature": [
{
"id": 1262,
"key": "name",
"value": "amd64"
}
]
}
],
"category": "cat1"
},
{
"id": 1357,
"name": "browser",
"value": [
{
"id": 1309,
"feature": [
{
"id": 1263,
"key": "name",
"value": "Firefox"
},
{
"id": 1265,
"key": "version",
"value": "187"
}
]
}
],
"category": "cat2"
}
]
},
{
"id": 2804,
"os": "window 7",
"features": [
{
"id": 2764,
"name": "architecture",
"value": [
{
"id": 2719,
"feature": [
{
"id": 2679,
"key": "name",
"value": "amd64"
}
]
}
],
"category": "cat1"
},
{
"id": 2765,
"name": "browser",
"value": [
{
"id": 2722,
"feature": [
{
"id": 2685,
"key": "name",
"value": "Chrome"
},
{
"id": 2684,
"key": "version",
"value": "87.0.4280.88"
}
]
}
],
"category": "cat2"
}
]
}
]
I want to be able to filter the json such that
features[*].name == 'browser' and features[*].value[*].feature[*].value == 'chrome'
What will be the JsonPath string that can help me achieve above query? The above query uses similar syntax used by JsonPath string but doesn't do the job. Its just to explain.
There is another example here gets Movie Title Given 'Starring' field
And would like to get the full OS json that fulfils this condition. In this case a array of OS which contains only one OS i.e. with id= 2804
[
{
"id": "2804",
...
}
]
I am stuck much before what aim to achieve. Here is my code to get all the OS that have "name=browser". I get the array but it only contains value[] items. I want it get the full json. It returns object with IDs- 1357, 2765.
List<Map<String, Object>> expensive = JsonPath.parse(jsonDataSourceString)
.read("$[*].features[*].[?(#.name == 'browser')]");
To get the outer array you need to use the filter like $[?(...)]
For your current use case, we need to use nested array filters. There is an open issue in JsonPath for filter on children level. (Refer here).
Luckily, there is a workaround suggested to use contains over here.
we can use the below expression to filter:
List<Object> expensive = JsonPath.parse(jsonDataSourceString)
.read("$[?(#.features[?(#.name == 'browser')].value[*].feature[*].value contains 'Chrome')]");
Prints the below output
{id=2804, os=window 7, features=[{"id":2764,"name":"architecture","value":[{"id":2719,"feature":[{"id":2679,"key":"name","value":"amd64"}]}],"category":"cat1"},{"id":2765,"name":"browser","value":[{"id":2722,"feature":[{"id":2685,"key":"name","value":"Chrome"},{"id":2684,"key":"version","value":"87.0.4280.88"}]}],"category":"cat2"}]}

how to update existing JSON file in java

This is my sample Json
{
"State": {
"version": "1",
"SName": "Test",
"shippingDetails": {
"Address1": "AP",
"ZipCode": "1236"
},
"Directions": {
"routes": [
{
"taxAmount": "0.0",
"Quantity": "5",
"bounds": {
"SerialVersion": [
{
"text": "1.7 km",
"value": "1729",
"time": "02633"
},
{
"text": "1.9 km",
"value": "1829",
"time": "02353"
},
{
"text": "17 km",
"value": "1059",
"time": "02133"
}
]
}
}
]
}
}
}
I want to update SName, ZipCode,taxAmount,Quantity, and text[1] values
are there any way to do this. I am taking JSON in a file and update tags are taking into HashMap
JSONObject jsonObject = new JSONObject("Your_JSON_String");
JSONObject jsonObjectForState = jsonObject.getJSONObject(“State”);
jsonObjectForState.put("Sname", "New_Value_Here");
put(...) will replace the current value with new value. Similarly, you can update the other values. Once you are done, you can convert it back using:
jsonObject.toString();
And write it back to the file.

How do I check if an element exists or not while JSON parsing?

I have the following json string. Sometimes, there are multiple definition elements and sometimes there is only one. I am new to JSON parsing and I somehow, in a very primitive way, managed to get the value of the first definition element that occurs. However, I am unable to get all values of definitions since there is no resource that I can find online. Do I have to check if second occurrence exists or is there a better way to do it ?
JSON:
{
"metadata": {
"provider": "Oxford University Press"
},
"results": [
{
"id": "edifice",
"language": "en",
"lexicalEntries": [
{
"entries": [
{
"etymologies": [
"late Middle English: via Old French from Latin aedificium, from aedis dwelling + facere make"
],
"grammaticalFeatures": [
{
"text": "Singular",
"type": "Number"
}
],
"senses": [
{
"definitions": [
"a large, imposing building."
],
"id": "m_en_gb0256160.001",
"registers": [
"formal"
]
},
{
"definitions": [
"a complex system of beliefs:"
],
"examples": [
{
"text": "the concepts on which the edifice of capitalism was built"
}
],
"id": "m_en_gb0256160.002",
"registers": [
"formal"
]
}
]
}
],
"language": "en",
"lexicalCategory": "Noun",
"pronunciations": [
{
"audioFile": "http://audio.oxforddictionaries.com/en/mp3/edifice_gb_1.mp3",
"dialects": [
"British English"
],
"phoneticNotation": "IPA",
"phoneticSpelling": "ˈɛdɪfɪs"
}
],
"text": "edifice"
}
],
"type": "headword",
"word": "edifice"
}
]
}
Java snippet to get definition value:
String locations = data.getJSONArray("results").getJSONObject(0).getJSONArray("lexicalEntries").getJSONObject(0).getJSONArray("entries").getJSONObject(0).getJSONArray("senses").getJSONObject(0).get("definitions").toString();
Everything looks good but you should stop at getJSONArray("senses").
It should be
JSONArray senses= .....getJSONArray("senses");
and then you should loop thru elements of that array. Something like this.
ArrayList<String> definitions = new ArrayList<String>();
for(int i =0; i < senses.length(); i++){
definitions.add(senses.getJSONObject(i).optString("definitions","");
}
But before doing that you should notice that your definitions json is not well formed it should be someting like
"definitions":"blablabl blablab"
Since it is not an array;.

Json : Content Parsing error

I have json file like this
[
{
"topic": "Example1",
"ref": {
"1": "Example Topic",
"2": "Topic"
},
"contact": [
{
"ref": [
1
],
"corresponding": true,
"name": "XYZ"
},
{
"ref": [
1
],
"name": "ZXY"
},
{
"ref": [
1
],
"name": "ABC"
},
{
"ref": [
1,
2
],
"name":"BCA"
}
] ,
"type": "Presentation"
}
]
I want to parse the ref array. I tried this. But showing error.
jsonArray.getJSONObject(index).getJSONArray("ref").getJSONObject(index).toString()
Now my question is
1) What is the correct way to parse that array's content.
The whole JSON is an array (starts with [). Its first element is an object (starts with {). This object has an attribute "ref". Its value is an object (starts with {).
So, to get this object, you need
jsonArray.getJSONObject(index).getJSONObject("ref")
I solved it By
JSONObject arJS = jsonArray.getJSONObject(index).getJSONObject("ref");
for(int counter = 1 ; jo<=jsonArray.getJSONObject(index).getJSONObject("ref").length();counter++){
String value = arJS.getString(String.valueOf(counter));
}

Get value from deep inside a JSONObject

I have this Bing Maps JSON file and I want to retrieve "++formattedAddress++" from inside it
{
"statusCode": 200,
"statusDescription": "OK",
"copyright": "Copyright © 2013 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
"authenticationResultCode": "ValidCredentials",
"resourceSets": [
{
"resources": [
{
"__type": "Location:http://schemas.microsoft.com/search/local/ws/rest/v1",
"point": {
"type": "Point",
"coordinates": [
63.8185213804245,
12.105498909950256
]
},
"matchCodes": [
"Good"
],
"address": {
"addressLine": "55 Stuff",
"locality": "Stuff",
"++formattedAddress++": "55 Stuff, 51512 Stuff",
"postalCode": "25521",
"adminDistrict2": "Stuff-Stuff",
"countryRegion": "UK",
"adminDistrict": "NL"
},
"bbox": [
84.81465866285382,
12.097347537264563,
50.822384097995176,
7.11365028263595
],
"name": "55 Stuff, 51122 Stuff",
"confidence": "Medium",
"entityType": "Address",
"geocodePoints": [
{
"calculationMethod": "Interpolation",
"type": "Point",
"usageTypes": [
"Display",
"Route"
],
"coordinates": [
50.8185213804245,
7.105498909950256
]
}
]
}
],
"estimatedTotal": 1
}
],
"traceId": "8a13f73cab93472db1253e4c1621c651|BL2M002306|02.00.83.1900|BL2MSNVM001274, BL2MSNVM003152",
"brandLogoUri": "http://dev.virtualearth.net/Branding/logo_powered_by.png"
}
What I have tried so far is like this:
final JSONArray jsonMainArr = locationData.getJSONArray("resourceSets").getJSONObject(0).getJSONArray("resources");
final JSONObject childJSONObject = jsonMainArr.getJSONObject(0);
return childJSONObject.getString("formattedAddress");
childJSONObject is still 2-3 levels over formattedAddress and the query is becoming highly inefficient
get formattedAddress address value as from current json String :
final JSONObject childJSONObject = jsonMainArr.getJSONObject(0)
.getJSONObject("address");
return childJSONObject.getString("++formattedAddress++");
There are so much online sites where you paste your complex code and get it in an easy way. e.g. http://json.parser.online.fr/

Categories

Resources