Google Dart JSON Extraction - json

I'm attempting to pull out data from a nested array in JSON but cannot seem to get the values correct. Right now, all values of the nested operatingSystem array print out in the table when I only need the name of the operating system. My code is below and please let me if you need more information.
Dart:
List<Map> assetList;
// LinkedHashMap preserves key entry order
LinkedHashMap<String, Map> dataMap = new LinkedHashMap<String, Map>();
for (var d in assetList) {
HashMap rowMap = new HashMap();
String domainId = d["process"]["processId"];
//first <td> element, the rest follow in succession
dataMap[domainId] = rowMap;
rowMap["domainId"] = domainId;
//is still not checking if null
if(d["asset"]["operatingSystem"].containsKey("name")){
rowMap["operatingSystem"] = d["asset"]["operatingSystem"]["name"];
} else{
rowMap["operatingSystem"] = d["asset"]["operatingSystem"];
}
//print out table data for debugging
print(rowMap.toString());
print(d);
JSON:
"asset":{
"assetId":"8a498592469189660146918d9e2f0000",
"oplock":0,
"domainName":"",
"latitude":58.92,
"ipAddress":"4.4.4.4",
"longitude":-37.23,
"operatingSystem":{
"osId":2,
"oplock":0,
"name":"Windows 8"
}
}

You need to go one level deeper. You are printing out the object's operatingSystem header but the operatingSystem header has 3 attributes.
The corect syntax is
json["asset"]["operatingSystem"]["name"];
You could also do it like this which I believe is more standard when it comes to JS and JSON
json.asset.operatingSystem.name

Related

Parsing a JSON API response

An API is giving me a JSON response like so :
{
"amountCredited":0,
"isFirstOrder":false,
"orderItems":[
{
"_id":624342e1c66be9001d501230,
"status":2,
"pinCode":749326,
"kioskId":61bb3982089a66001db4ab77,
"kioskActivityId":620668ad433322b99557c874
}
]
}
I'm trying to access the data inside the "orderItems" in order to feed it to an existing parsing model in the App
order = OrderItemModel.fromJson(response.body['orderItems'] as Map<String, dynamic>);
but since the data inside orderItems JSON response is inside an array I can't access it this way..
How can I access it knowing that this JSON "orderItems" array will always only have one item as a response ?
Would something like response.body['orderItems' : [0]] enable me to access the first item data ?
Since you always know that the array will always have only one item. We'll first make it a List & then access the first element.
order = OrderItemModel.fromJson((response.body['orderItems'] as List<dynamic>).first as Map<String, dynamic>);
To understand it a bit better refer to the code below:
The JSON response contains an array, which we need to access.
final ordersArray = response.body['orderItems'] as List<dynamic>;
Then we want to access the first order (according to the question)
final firstOrder = ordersArray.first as Map<String, dynamic>;
Once we have the order, we'll convert it to the model
final order = OrderItemModel.fromJson(firstOrder);
EDIT:
as it was pointed out in a comment List objects have a getter called first which can be used to get the first element, the code has been updated with that.
You need to convert as Map and List because Flutter deal only with this datatypes. For example:
Map order1 = {
"_id":"624342e1c66be9001d501230",
"status":2,
"pinCode":749326,
"kioskId":"61bb3982089a66001db4ab77",
"kioskActivityId":"620668ad433322b99557c874"
};
Map order2 = {
"_id":"224342e1c66be9001d501232",
"status":1,
"pinCode":248023,
"kioskId":"41bb3982089a66001db4ab74",
"kioskActivityId":"720668ad433322b99557c875"
};
Map m = {
"amountCredited":0,
"isFirstOrder":false,
"orderItems":[
order1,
order2
]
};
print(m['orderItems'][1]);
print(m['orderItems'][1]['pinCode']);
The result will be:
{_id: 224342e1c66be9001d501232, status: 1, pinCode: 248023, kioskId: 41bb3982089a66001db4ab74, kioskActivityId: 720668ad433322b99557c875}
248023

Is there a XPath with schema equivilent for JSON? [duplicate]

I have JSON as a string and a JSONPath as a string. I'd like to query the JSON with the JSON path, getting the resulting JSON as a string.
I gather that Jayway's json-path is the standard. The online API, however, doesn't have have much relation to the actual library you get from Maven. GrepCode's version roughly matches up though.
It seems like I ought to be able to do:
String originalJson; //these are initialized to actual data
String jsonPath;
String queriedJson = JsonPath.<String>read(originalJson, jsonPath);
The problem is that read returns whatever it feels most appropriate based on what the JSONPath actually finds (e.g. a List<Object>, String, double, etc.), thus my code throws an exception for certain queries. It seems pretty reasonable to assume that there'd be some way to query JSON and get JSON back; any suggestions?
Java JsonPath API found at jayway JsonPath might have changed a little since all the above answers/comments. Documentation too. Just follow the above link and read that README.md, it contains some very clear usage documentation IMO.
Basically, as of current latest version 2.2.0 of the library, there are a few different ways of achieving what's been requested here, such as:
Pattern:
--------
String json = "{...your JSON here...}";
String jsonPathExpression = "$...your jsonPath expression here...";
J requestedClass = JsonPath.parse(json).read(jsonPathExpression, YouRequestedClass.class);
Example:
--------
// For better readability: {"store": { "books": [ {"author": "Stephen King", "title": "IT"}, {"author": "Agatha Christie", "title": "The ABC Murders"} ] } }
String json = "{\"store\": { \"books\": [ {\"author\": \"Stephen King\", \"title\": \"IT\"}, {\"author\": \"Agatha Christie\", \"title\": \"The ABC Murders\"} ] } }";
String jsonPathExpression = "$.store.books[?(#.title=='IT')]";
JsonNode jsonNode = JsonPath.parse(json).read(jsonPathExpression, JsonNode.class);
And for reference, calling 'JsonPath.parse(..)' will return an object of class 'JsonContent' implementing some interfaces such as 'ReadContext', which contains several different 'read(..)' operations, such as the one demonstrated above:
/**
* Reads the given path from this context
*
* #param path path to apply
* #param type expected return type (will try to map)
* #param <T>
* #return result
*/
<T> T read(JsonPath path, Class<T> type);
Hope this help anyone.
There definitely exists a way to query Json and get Json back using JsonPath.
See example below:
String jsonString = "{\"delivery_codes\": [{\"postal_code\": {\"district\": \"Ghaziabad\", \"pin\": 201001, \"pre_paid\": \"Y\", \"cash\": \"Y\", \"pickup\": \"Y\", \"repl\": \"N\", \"cod\": \"Y\", \"is_oda\": \"N\", \"sort_code\": \"GB\", \"state_code\": \"UP\"}}]}";
String jsonExp = "$.delivery_codes";
JsonNode pincodes = JsonPath.read(jsonExp, jsonString, JsonNode.class);
System.out.println("pincodesJson : "+pincodes);
The output of the above will be inner Json.
[{"postal_code":{"district":"Ghaziabad","pin":201001,"pre_paid":"Y","cash":"Y","pickup":"Y","repl":"N","cod":"Y","is_oda":"N","sort_code":"GB","state_code":"UP"}}]
Now each individual name/value pairs can be parsed by iterating the List (JsonNode) we got above.
for(int i = 0; i< pincodes.size();i++){
JsonNode node = pincodes.get(i);
String pin = JsonPath.read("$.postal_code.pin", node, String.class);
String district = JsonPath.read("$.postal_code.district", node, String.class);
System.out.println("pin :: " + pin + " district :: " + district );
}
The output will be:
pin :: 201001 district :: Ghaziabad
Depending upon the Json you are trying to parse, you can decide whether to fetch a List or just a single String/Long value.
Hope it helps in solving your problem.
For those of you wondering why some of these years-old answers aren't working, you can learn a lot from the test cases.
As of September 2018, here's how you can get Jackson JsonNode results:
Configuration jacksonConfig = Configuration.builder()
.mappingProvider( new JacksonMappingProvider() )
.jsonProvider( new JacksonJsonProvider() )
.build();
JsonNode node = JsonPath.using( jacksonConfig ).parse(jsonString);
//If you have a json object already no need to initiate the jsonObject
JSONObject jsonObject = new JSONObject();
String jsonString = jsonObject.toString();
String path = "$.rootObject.childObject"
//Only returning the child object
JSONObject j = JsonPath.read(jsonString, path);
//Returning the array of string type from the child object. E.g
//{"root": "child":[x, y, z]}
List<String> values = sonPath.read(jsonString, path);
Check out the jpath API. It's xpath equivalent for JSON Data. You can read data by providing the jpath which will traverse the JSON data and return the requested value.
This Java class is the implementation as well as it has example codes on how to call the APIs.
https://github.com/satyapaul/jpath/blob/master/JSONDataReader.java
Readme -
https://github.com/satyapaul/jpath/blob/master/README.md

Parsing JSON Data from URL with Android Studio

I'm trying to parse JSON data from URL and show the data in my app.
JSON Example (After accessing specific URL):
[{"placeID":"1","placeName":"Test Place","city":"New York","type":"Rest"..
How I can read this data and show a list of the places recieved from the API?
I've been trying ALL of the guides over the internet for parsing JSON data from URL with Android Studio and without. As a total beginner with Android developement, I couldn't make one working exmaple with json even when the author shared the final example for download. I hope you can help me in noob-friendly way and step by step or refer me to the right places.
Thank you!
I believe Android uses org.json as the JSON library, in which case something like this works to retrieve information about each place (assuming data is a valid JSON string)
try {
String data = "\"[{\"placeID\":\"1\",\"placeName\":\"Test Place\",\"city\":\"New York\",\"type\":\"Rest\"..";
JSONArray places = new JSONArray(data);
for (int i = 0; i < places.length(); i++)
JSONObject place = (JSONObject) places.get(i);
int id = place.getInt("id");
String name = place.getString("placeName");
String city = place.getString("city");
// etc...
// Do what you wish with the id, name, city and other variables.
// It loops through here for each item in the JSON variable.
}
} catch (JSONException e) {
e.printStackTrace();
}
This goes through each place in the JSON array and grabs some of the variables from it. It would probably be smart to create a data class and call it something like Place. You could then pass in the data with a constructor: new Place(id, name, city); (see this constructor for example: https://stackoverflow.com/a/22419370/5236779).

Grails: Easy and efficient way to parse JSON from a Request

Please pardon me if this is a repeat question. I have been through some of the questions/answers with a similar requirement but somehow got a bit overwhelmed and confused at the same time. My requirement is:
I get a JSON string/object as a request parameter. ( eg: params.timesheetJSON )
I then have to parse/iterate through it.
Here is the JSON that my grails controller will be receiving:
{
"loginName":"user1",
"timesheetList":
[
{
"periodBegin":"2014/10/12",
"periodEnd":"2014/10/18",
"timesheetRows":[
{
"task":"Cleaning",
"description":"cleaning description",
"paycode":"payCode1"
},
{
"task":"painting",
"activityDescription":"painting description",
"paycode":"payCode2"
}
]
}
],
"overallStatus":"SUCCESS"
}
Questions:
How can I retrieve the whole JSON string from the request? Does request.JSON be fine here? If so, will request.JSON.timesheetJSON yield me the actual JSON that I want as a JSONObject?
What is the best way to parse through the JSON object that I got from the request? Is it grails.converters.JSON? Or is there any other easy way of parsing through? Like some API which will return the JSON as a collection of objects by automatically taking care of parsing. Or is programatically parsing through the JSON object the only way?
Like I said, please pardon me if the question is sounding vague. Any good references JSON parsing with grails might also be helpful here.
Edit: There's a change in the way I get the JSON string now. I get the JSON string as a request paramter.
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON) // No problem here. Returns a JSONObject. I checked the class type.
def jsonArray = jsonArray.timesheetList // No problem here. Returns a JSONArray. I checked the class type.
println "*** Size of jsonArray1: " + jsonArray1.size() // Returns size 1. It seemed fine as the above JSON string had only one timesheet in timesheetList
def object1 = jsonArray[1] // This throws the JSONException, JSONArray[1] not found. I tried jsonArray.getJSONObject(1) and that throws the same exception.
Basically, I am looking to seamlessly iterate through the JSON string now.
I have wrote some code that explains how this can be done, that you can see below, but to be clear, first the answers to your questions:
Your JSON String as you wrote above will be the contents of your POST payload to the rest controller. Grails will use its data binding mechanism to bind the incomming data to a Command object that your should prepare. It has to have fields corresponding to the parameters in your JSON String (see below). After you bind your command object to your actual domain object, you can get all the data you want, by simply operating on fields and lists
The way to parse thru the JSON object is shown in my example below. The incomming request is esentially a nested map, with can be simply accessed with a dot
Now some code that illustrates how to do it.
In your controller create a method that accepts "YourCommand" object as input parameter:
def yourRestServiceMethod (YourCommand comm){
YourClass yourClass = new YourClass()
comm.bindTo(yourClass)
// do something with yourClass
// println yourClass.timeSheetList
}
The command looks like this:
class YourCommand {
String loginName
List<Map> timesheetList = []
String overallStatus
void bindTo(YourClass yourClass){
yourClass.loginName=loginName
yourClass.overallStatus=overallStatus
timesheetList.each { sheet ->
TimeSheet timeSheet = new TimeSheet()
timeSheet.periodBegin = sheet.periodBegin
timeSheet.periodEnd = sheet.periodEnd
sheet.timesheetRows.each { row ->
TimeSheetRow timeSheetRow = new TimeSheetRow()
timeSheetRow.task = row.task
timeSheetRow.description = row.description
timeSheetRow.paycode = row.paycode
timeSheet.timesheetRows.add(timeSheetRow)
}
yourClass.timeSheetList.add(timeSheet)
}
}
}
Its "bindTo" method is the key piece of logic that understands how to get parameters from the incomming request and map it to a regular object. That object is of type "YourClass" and it looks like this:
class YourClass {
String loginName
Collection<TimeSheet> timeSheetList = []
String overallStatus
}
all other classes that are part of that class:
class TimeSheet {
String periodBegin
String periodEnd
Collection<TimeSheetRow> timesheetRows = []
}
and the last one:
class TimeSheetRow {
String task
String description
String paycode
}
Hope this example is clear enough for you and answers your question
Edit: Extending the answer according to the new requirements
Looking at your new code, I see that you probably did some typos when writting that post
def jsonArray = jsonArray.timesheetList
should be:
def jsonArray = jsonObject.timesheetList
but you obviously have it properly in your code since otherwise it would not work, then the same with that line with "println":
jsonArray1.size()
shuold be:
jsonArray.size()
and the essential fix:
def object1 = jsonArray[1]
shuold be
def object1 = jsonArray[0]
your array is of size==1, the indexing starts with 0. // Can it be that easy? ;)
Then "object1" is again a JSONObject, so you can access the fields with a "." or as a map, for example like this:
object1.get('periodEnd')
I see your example contains errors, which lead you to implement more complex JSON parsing solutions.
I rewrite your sample to the working version. (At least now for Grails 3.x)
String saveJSON // This holds the above JSON string.
def jsonObject = grails.converters.JSON.parse(saveJSON)
println jsonObject.timesheetList // output timesheetList structure
println jsonObject.timesheetList[0].timesheetRows[1] // output second element of timesheetRows array: [paycode:payCode2, task:painting, activityDescription:painting description]

Couchbase - deserialize json into dynamic type

I'm trying to deserialize some JSON coming back from couchbase into a dynamic type.
The document is something like this so creating a POCO for this would be overkill:
{
UsersOnline: 1
}
I figured that something like this would do the trick, but it seems to deserialize into a dynamic object with the value just being the original JSON
var jsonObj = _client.GetJson<dynamic>(storageKey);
results in:
jsonObj { "online": 0 }
Is there anyway I can get the couchbase deserializer to generate the dynamic type for me?
Cheers
The default deserializer for the client uses .NET's binary serializer, so when you save or read a JSON string, it's just a string. GetJson will always just return a string. However, there are a couple of options:
You could convert JSON records to Dictionary instances:
var appJson = "{ \"UsersOnline\" : 1, \"NewestMember\" : \"zblock\" }";
var result = client.ExecuteStore(StoreMode.Set, "userCount", appJson);
var item = client.GetJson<Dictionary<string, object>>("userCount");
Console.WriteLine("There are {0} users online. The newest member is {1}.",
item["UsersOnline"], item["NewestMember"]);
Or you could use a dynamic ExpandoObject instance:
var appJson = "{ \"UsersOnline\" : 1, \"NewestMember\" : \"zblock\" }";
var result = client.ExecuteStore(StoreMode.Set, "userCount", appJson);
dynamic item = client.GetJson<ExpandoObject>("userCount");
Console.WriteLine("There are {0} users online. The newest member is {1}.",
item.UsersOnline, item.NewestMember);
In either case you're losing static type checking, which seems like it's OK for your purposes. In both cases you get access to the JSON properties without having to parse the JSON into a POCO though...
Edit: I wrote a couple of extension methods that may be useful and blogged about them at http://blog.couchbase.com/moving-no-schema-stack-c-and-dynamic-types