Selected read JSON by url - java

I want to make my code as simple as I can and don't want to download items which are not needed.
I want to select only Pages when I'm admin on facebook.
For now I use:
https://graph.facebook.com/v2.0/me/?fields=id,accounts{id,perms}&summary=true&limit=100&access_token=MY_TOKEN
Results:
{
"id": "101506",
"accounts": {
"data": [
{
"id": "6986842335",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
{
"id": "1374577066121",
"perms": [
"BASIC_ADMIN"
]
},
{
"id": "997587036984",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
],
}
}
Now, how to change the query to read only items with perms=ADMINISTER ?
This is what I need:
{
"id": "101506",
"accounts": {
"data": [
{
"id": "6986842335",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
{
"id": "997587036984",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
},
],
}
}
If I can't make the query to read what I need, maybe you know how to do this in Java to check the length of pages?
For now I have:
User = facebookClient.fetchObject("v2.0/me", JsonObject.class, Parameter.with("summary", true), Parameter.with("fields", "id,name,accounts{id,perms}"), Parameter.with("limit", 100));
Integer userFPCount = User.getJsonObject("accounts").getJsonArray("data").length();
But this code gives me results: 3. How to check the length of accounts.data.perms(ADMINISTER) ? I should have result: 2 in this example.
THANK YOU FOR YOUR HELP !

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 collect all other values for a tag within JSON even when the exception `com.jayway.jsonpath.PathNotFoundException` is thrown?

Consider the code snippet below-
{
"header": {
"systemId": "1"
},
"body": {
"approvalType": "S",
"requester": "CRM",
"approver": "V",
"additionalInfoList": [
{
"additionalInfoItem": {
"value": [
{
"secret": [
{
"question": "1"
}
]
},
{
"secret": [
{
"question": "2"
}
]
},
{
"secret": [
{
"question": "3"
}
]
}
]
}
},
{
"additionalInfoItem": {
"name": "key2",
"value": [
{
"secret": [
{
"question": "00"
}
]
},
{
"secret": [
{
"question": "002"
}
]
},
{
"secret": [
{
"question": "003"
}
]
}
]
}
}
]
}
}
For this json path
$.body.additionalInfoList[*].additionalInfoItem.value[*].secret[*].question
the API gives
[
"1",
"2",
"3",
"00",
"002",
"003"
]
I am using configuration REQUIRE_PROPERTIES option which configures JsonPath to require properties defined in path when an indefinite path is evaluated.
If in the above JSON, one of the question is not sent in request, an exception as below will be thrown - No results for path: $['body']['additionalInfoList'][1]['additionalInfoItem']['value'][0]['secret'][0]['question']
I have a requirement to collect all other values for the question tag even when the exception com.jayway.jsonpath.PathNotFoundException was thrown. How can I achieve this?
On the other hand, if I use the option SUPPRESS_EXCEPTIONS, how can I know if there is a missing path?
I do not have a great answer here; however, to get it done I would suggest processing the response twice:
once with SUPPRESS_EXCEPTIONS (or simply no option might work as well),
and then with REQUIRE_PROPERTIES to detect the errors.
This should allow you to handle the scenario as described.

Jayway JsonPath query to get required json format

I need to extract a json in required format from input json. i'm using jayway json path library. How to achieve it ?
Input Json:
{
"ccid": [
{
"id": 13,
"src": {
"sname": "XA-SXXD",
"lname": "John",
"identifier": 2,
"StatusCode": "C"
}
},
{
"id": 14,
"src": {
"sname": "XB-SXXD",
"lname": "Cena",
"identifier": 3,
"StatusCode": "C",
}
}
]
}
Required Format:
[ {
"id": "13",
"sources": {
"sname": "XA-SXXD",
"lname": "John",
"identifier": 2
}
},
{
"id": "14",
"sources": {
"sname": "XB-SXXD",
"lname": "Cena",
"identifier": 3
}
}]
Query that i use:
$.ccid[*].src[?(#.identifier!=null)].['identifier','sname']
Output that i get:
[
{
"identifier" : 2,
"sname" : "XA-SXXD"
},
{
"identifier" : 3,
"sname" : "XB-SXXD"
}
]
Kindly help me to modify my query to get the required format. The string "sources" in the required format can be hardcoded.
I think I managed to solve this :)
$.ccid[*].[?(#.src.identifier!=null)].['id', 'src']
Give it a try.
Input tested on:
{
"ccid": [
{
"id": 13,
"src": {
"sname": "XA-SXXD",
"lname": "John",
"StatusCode": "C"
}
},
{
"id": 14,
"src": {
"sname": "XB-SXXD",
"lname": "Cena",
"identifier": null,
"StatusCode": "C",
}
}
]
}
Output received:
[
{
"id" : 13,
"src" : {
"sname" : "XA-SXXD",
"lname" : "John",
"StatusCode" : "C"
}
}
]
Only problem is saw is if identifier tag is not available it's essentially treated as not-null. Hence we are getting 13 as an output. But if value is explicitly null then it's fine. So the needs to be enhanced a bit more.
Hope this helps.

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));
}

Categories

Resources