How to Show "Category" , according to Category "Title", & "Price"
in RecyclerView One Row.
my Api url is https://www.paidup.io/api/v1/businesses/212/menu
This Url returns response like:
[{
"category": "Espresso & Coffee",
"items": [{
"title": "Vacuum Coffee",
"size": [{
"label": "medium",
"price": 125
}, {
"label": "large",
"price": 145
}]
}, {
"title": "Cafe Latte",
"size": [{
"label": "small",
"price": 115
}, {
"label": "medium",
"price": 135
}, {
"label": "large",
"price": 150
}]
}, {
"title": "Cafe Mocha",
"size": [{
"label": "small",
"price": 115
}, {
"label": "medium",
"price": 135
}, {
"label": "large",
"price": 150
}]
}, {
"title": "White Mocha",
"size": [{
"label": "small",
"price": 120
}, {
"label": "medium",
"price": 145
}, {
"label": "large",
"price": 155
}]
}, {
"title": "Caramel Macchiato",
"size": [{
"label": "small",
"price": 125
}, {
"label": "medium",
"price": 145
}, {
"label": "large",
"price": 165
}]
}, {
"title": "Coffee De Leche",
"size": [{
"label": "small",
"price": 130
}, {
"label": "medium",
"price": 145
}, {
"label": "large",
"price": 160
}]
}, {
"title": "Cafe-UK Coffee Lava",
"size": null,
"price": 145
}]
}, {
"category": "Frappe",
"items": [{
"title": "Coffee Base",
"size": [{
"label": "small",
"price": 140
}, {
"label": "medium",
"price": 155
}, {
"label": "large",
"price": 170
}]
}, {
"title": "Milk Base",
"size": [{
"label": "small",
"price": 130
}, {
"label": "medium",
"price": 145
}, {
"label": "large",
"price": 160
}]
}, {
"title": "Cream Soda Float w\/Ice-cream",
"size": null,
"price": 140
}]
}, {
"category": "Milk Tea & Juice",
"items": [{
"title": "Milk Tea",
"size": [{
"label": "small",
"price": 105
}, {
"label": "medium",
"price": 120
}]
}, {
"title": "Hot Tea",
"size": null,
"price": 120
}, {
"title": "Italian Soda",
"size": [{
"label": "small",
"price": 105
}, {
"label": "medium",
"price": 120
}, {
"label": "large",
"price": 140
}]
}, {
"title": "Juice",
"size": null,
"price": 105
}]
}, {
"category": "Food",
"items": [{
"title": "Ultimate Chili Con Fries",
"size": null,
"price": 290
}, {
"title": "Nachos",
"size": null,
"price": 290
}, {
"title": "Marble Potato Fondue",
"size": null,
"price": 120
}, {
"title":"Breakfast",
"size":null,
"price":220
}]}]
and my POJO Classes are Like:
package ph.paidup.models;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
/**
* Created by oxiloindia on 3/30/2016.
*/
public class Item {
#SerializedName("title")
#Expose
private String title;
#SerializedName("size")
#Expose
private Object size;
#SerializedName("price")
#Expose
private Integer price;
/**
*
* #return
* The title
*/
public String getTitle() {
return title;
}
/**
*
* #param title
* The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
*
* #return
* The size
*/
public Object getSize() {
return size;
}
/**
*
* #param size
* The size
*/
public void setSize(Object size) {
this.size = size;
}
/**
*
* #return
* The price
*/
public Integer getPrice() {
return price;
}
/**
*
* #param price
* The price
*/
public void setPrice(Integer price) {
this.price = price;
}
}
and another class:
package ph.paidup.models;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
/**
* Created by oxiloindia on 3/30/2016.
*/
#Generated("org.jsonschema2pojo")
public class MenuRequest {
#SerializedName("category")
#Expose
private String category;
#SerializedName("items")
#Expose
private List<Item> items = new ArrayList<Item>();
/**
*
* #return
* The category
*/
public String getCategory() {
return category;
}
/**
*
* #param category
* The category
*/
public void setCategory(String category) {
this.category = category;
}
/**
*
* #return
* The items
*/
public List<Item> getItems() {
return items;
}
/**
*
* #param items
* The items
*/
public void setItems(List<Item> items) {
this.items = items;
}
}
Now i want to parse this in my Activity to Get
According to
"category" , needs its
"title" and
"price" in recyclerview
i am Trying to do it Like this way:
public void getInVoice() {
showProgress(true);
String URL="https://www.paidup.io/api/v1/businesses/212/menu";
JsonArrayRequest req = new JsonArrayRequest(Request.Method.GET,URL,null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
showProgress(false);
VolleyLog.v("Response:%n %s", response);
Gson gson = new GsonBuilder().create();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = new JSONObject();
String desc = jsonObject.getString("category");
JsonParser jsonParser = new JsonParser();
groupItem.items = (List<Item>) jsonParser.parse(String.valueOf(response));
// Create a new adapter with data items
mExpandableAdapter = new BakeryMenuExpandableAdapter(getActivity(), setUpList(groupItem.items)) {
#Override
public void onItemClick(int position, View v) {
}
};
// Attach this activity to the Adapter as the ExpandCollapseListener
mExpandableAdapter.setExpandCollapseListener(new ExpandableRecyclerAdapter.ExpandCollapseListener() {
#Override
public void onListItemExpanded(int position) {
Log.e("CHEEE", "" + position);
}
#Override
public void onListItemCollapsed(int position) {
}
});
// Set the RecyclerView's adapter to the ExpandableAdapter we just created
recyclerView.setAdapter(mExpandableAdapter);
// Set the layout manager to a LinearLayout manager for vertical list
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
} catch (Exception e) {
Log.e("My App", "Could not parse malformed JSON: \"" + response + "\"");
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Activity activity = getActivity();
if (activity != null && isAdded())
showProgress(false);
Toast.makeText(getActivity(), "Something went wrong. please try it again", Toast.LENGTH_SHORT).show();
}
});
// add the request object to the queue to be executed
addToRequestQueue(req, TAG);
}
I tried all Requests to Parse it but couldn't get success.
What should i need to do in Try block to get List of Items for recyclerview
thanks in advance....plz solve it
You have errors in your response callback.
1) You use JsonRequest of volley but you actually want to parse it into a POJO with Gson.
2) you get array of menurequest objects but it seems you handle then as just one MenuRequest
so you don't really need those:
JSONObject jsonObject = new JSONObject();
String desc = jsonObject.getString("category");
JsonParser jsonParser = new JsonParser();
groupItem.items = (List<Item>) jsonParser.parse(String.valueOf(response));
These actually throws different exceptions.
instead you can do:
MenuRequest[] items = gson.fromJson(response.toString(), MenuRequest[].class);
so in items you will endup with an Array of MenuRequest objects
then you can do whatever you need for example:
for(MenuRequest item:items) {
Log.d("test", "item: " +item);
}
Related
I’m working on splitting a SignalK JSON object into canonical JSON items representing each value.
The original JSON looks like this:
{
"mmsi": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"name": "Mona",
"navigation": {
"position": {
"timestamp": "1991-09-03T03:5:36.000Z",
"latitude": 51.763691,
"longitude": 9.501367,
"altitude": 0.000000,
"source": "N0183-01"
},
"courseOverGroundTrue": {
"value": 23.000000
},
"speedOverGround": {
"value": 2.010289
}
},
"environment": {
"depth": {
"belowTransducer": {
"value": 12.700000
}
},
"wind": {
"angleApparent": {
"value": 0.174533
},
"speedApparent": {
"value": 0.000000
}
}}}
The needed transformed JSON looks like this, with JSON elements representing each value, and with item naming representing the whole path of the value.
{
"items": [{
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "EnvironmentWindSpeedApparent",
"isStep": false,
"name": "EnvironmentWindSpeedApparent",
"timestamps": 1523962903470,
"type": "numerical",
"values": 0.0
},
"key": "20180417-130143470EnvironmentWindSpeedApparent5377770-4ee4-4a4b-3230-888037332031"
}, {
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "EnvironmentWindAngleApparent",
"isStep": false,
"name": "EnvironmentWindAngleApparent",
"timestamps": 1523962903470,
"type": "numerical",
"values": 0.174533
},
"key": "20180417-130143470EnvironmentWindAngleApparent5377770-4ee4-4a4b-3230-888037332031"
}, {
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "EnvironmentDepthBelowTransducer",
"isStep": false,
"name": "EnvironmentDepthBelowTransducer",
"timestamps": 1523962903470,
"type": "numerical",
"values": 12.7
},
"key": "20180417-130143470EnvironmentDepthBelowTransducer5377770-4ee4-4a4b-3230-888037332031"
}, {
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "NavigationPositionLongitude",
"isStep": false,
"name": "NavigationPositionLongitude",
"timestamps": 1523962903470,
"type": "numerical",
"values": 9.501367
},
"key": "20180417-130143470NavigationPositionLongitude5377770-4ee4-4a4b-3230-888037332031"
}, {
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "NavigationPositionLatitude",
"isStep": false,
"name": "NavigationPositionLatitude",
"timestamps": 1523962903470,
"type": "numerical",
"values": 51.763691
},
"key": "20180417-130143470NavigationPositionLatitude5377770-4ee4-4a4b-3230-888037332031"
}, {
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "NavigationCourseOverGroundTrue",
"isStep": false,
"name": "NavigationCourseOverGroundTrue",
"timestamps": 1523962903470,
"type": "numerical",
"values": 23.0
},
"key": "20180417-130143470NavigationCourseOverGroundTrue5377770-4ee4-4a4b-3230-888037332031"
}, {
"columns": {
"assetId": "urn:mrn:signalk:uuid:5377770-4ee4-4a4b-3230-888037332031",
"description": "NavigationSpeedOverGround",
"isStep": false,
"name": "NavigationSpeedOverGround",
"timestamps": 1523962903470,
"type": "numerical",
"values": 2.010289
},
"key": "20180417-130143470NavigationSpeedOverGround5377770-4ee4-4a4b-3230-888037332031"
}
]}
How to do this transformation in a flexible way that adopts to changing sub-nodes being available in the original JSON ?
I’m transforming it now in a simplistic way, but would like to know if it can be done using JsonReader , gson or other ways of iterating through the original JSON object.
I ended up defining the object structure representing the transformed json, and writing a custom serializer to do the transformation. It could be more efficient ways of doing it, but this approach seems to be working OK.
public class SignalKDeserializer implements JsonDeserializer<TargetObject> {
//written based on examples from http://www.javacreed.com/gson-deserialiser-example/
final TargetObject targetObject = new TargetObject ();
#Override
public TargetObject deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context)
throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
traverse (jsonObject,0,"", mmsi);
return targetObject;
}
private void traverse (JsonObject jsonObject, Integer level, String parentName, String mmsi) {
Set<String> keys = jsonObject.keySet();
Iterator<?> keysIterator = keys.iterator ();
while( keysIterator.hasNext ()) {
String key = (String) keysIterator.next ();
String signalName = parentName+upperCaseFirst (key); //setting signalName to complete path of value
if (jsonObject.get (key) instanceof JsonObject) {
traverse ((jsonObject.get (key)).getAsJsonObject (),level+1,upperCaseFirst (signalName),mmsi);
} else if (jsonObject.get (key) instanceof JsonElement) {
if (level>0) {
try {
final Double value = jsonObject.get(key).getAsDouble ();
calendar = Calendar.getInstance ();
Long timeStamp = calendar.getTimeInMillis ();
Item targetItem = new Item ();
targetItem.columns.setIsStep (false);
targetItem.columns.setAssetId (mmsi);
targetItem.columns.setTimestamps (calendar.getTimeInMillis ());
targetItem.columns.setType ("numerical");
targetItem.columns.setDescription (signalName);
targetItem.columns.setValues (value);
targetItem.columns.setName (signalName);
targetItem.setKey (signaldateformat.format (timeStamp) + mmsi);
targetObject.items.add (targetItem);
}
catch (NumberFormatException n) {
// Expected, the value is non numerical and will not be transformed
}
}
}
}
}}
I'm using the serializer from my main class like this:
final GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(TargetObject.class, new SignalKDeserializer ());
final Gson gson = gsonBuilder.create();
TargetObject targetObject = gson.fromJson (jsonSignalK,TargetObject.class);
String jsonOutString = gson.toJson (targetObject);
jsonOutString contains the transformed json I needed.
I connected to saber InstaFlight API and got a result in JSON. The output string is too long and I can get their values. But my way is taking lots of memory storage. I want a way that takes less memory storage and a dynamic way in VB.NET.
The code below is working fine with no error:
response2 = DirectCast(postReq.GetResponse(), HttpWebResponse)
reader2 = New StreamReader(response2.GetResponseStream())
postReq.ContentType = "application/json; charset=utf-8"
Dim ser1 As JObject = JObject.Parse(reader2.ReadToEnd())
I can get the values like this, with no error:
ElapseTime1 = ser1("PricedItineraries")(0)("AirItinerary")("OriginDestinationOptions")("OriginDestinationOption")(0)("ElapsedTime").Value(Of String)()
However, it gets to a point that you need hundreds of variables and this is not the right way.
An example of the output JSON:
{ "PricedItineraries": [ { "AirItinerary": { "OriginDestinationOptions": { "OriginDestinationOption": [ { "FlightSegment": [ { "DepartureAirport": { "LocationCode": "JFK" }, "ArrivalAirport": { "LocationCode": "LAS" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -7 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0, "ElapsedTime": 344, "ResBookDesigCode": "R", "MarriageGrp": "O", "Equipment": { "AirEquipType": 320 }, "DepartureDateTime": "2017-07-07T09:30:00", "ArrivalDateTime": "2017-07-07T12:14:00", "FlightNumber": 1251, "OnTimePerformance": { "Percentage": 70 }, "OperatingAirline": { "CompanyShortName": "VIRGIN AMERICA", "FlightNumber": 251, "Code": "VX" }, "DepartureTimeZone": { "GMTOffset": -4 } }, { "DepartureAirport": { "LocationCode": "LAS" }, "ArrivalAirport": { "LocationCode": "LAX" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -7 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0, "ElapsedTime": 85, "ResBookDesigCode": "R", "MarriageGrp": "O", "Equipment": { "AirEquipType": 320 }, "DepartureDateTime": "2017-07-07T14:45:00", "ArrivalDateTime": "2017-07-07T16:10:00", "FlightNumber": 1475, "OnTimePerformance": { "Percentage": 36 }, "OperatingAirline": { "CompanyShortName": "VIRGIN AMERICA", "FlightNumber": 475, "Code": "VX" }, "DepartureTimeZone": { "GMTOffset": -7 } } ], "ElapsedTime": 580 }, { "FlightSegment": [ { "DepartureAirport": { "LocationCode": "LAX" }, "ArrivalAirport": { "LocationCode": "LAS" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -7 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0, "ElapsedTime": 71, "ResBookDesigCode": "R", "MarriageGrp": "O", "Equipment": { "AirEquipType": 320 }, "DepartureDateTime": "2017-07-08T17:00:00", "ArrivalDateTime": "2017-07-08T18:11:00", "FlightNumber": 1480, "OnTimePerformance": { "Percentage": 55 }, "OperatingAirline": { "CompanyShortName": "VIRGIN AMERICA", "FlightNumber": 480, "Code": "VX" }, "DepartureTimeZone": { "GMTOffset": -7 } }, { "DepartureAirport": { "LocationCode": "LAS" }, "ArrivalAirport": { "LocationCode": "JFK" }, "MarketingAirline": { "Code": "AS" }, "ArrivalTimeZone": { "GMTOffset": -4 }, "TPA_Extensions": { "eTicket": { "Ind": true } }, "StopQuantity": 0,
I think you need to create a model for this result. According to this JSON, you have to create a class model.
If you have this JSON:
{
"dailyDealId": "432",
"discountPercentage": "0",
"product": {
"productId": "10",
"brandId": "10",
"departmentId": "3",
"name": "Baby Girl Velour Tunic & Snowflake Legging Set",
"description": "The pretty set",
"url": "http://whatever.whatever.com/files/whatever.tif"
}
You need this model:
public class Product
{
public string productId { get; set; }
public string brandId { get; set; }
public string departmentId { get; set; }
public string name { get; set; }
public string description { get; set; }
public string url { get; set; }
}
public class Data
{
public string dailyDealId { get; set; }
public string discountPercentage { get; set; }
public Product product { get; set; }
}
I'm trying to return json with two classes in my model
public function both()
{
return $this->belongsToMany(Car::class)->and(Driver::class)->withPivot('type'); // this is wrong
}
the reason I'm trying to get this like that is because in my function
public function check()
{
$user = JWTAuth::parseToken()->authenticate();
$id = $user->id;
$result = User::with('both')->where('id', $id)->get();
return response()->json($result);
}
right now in my model I have this
public function both()
{
return $this->belongsToMany(Car::class)->withPivot('type');
}
public function driver()
{
return $this->belongsToMany(Driver::class)->withPivot('type');
}
But the function returns json that has a different structure when both ends.
My question is can I have the function return a json with the same structure?
like this
[
{
"id": 4,
"name": null,
"phone": "9000",
"size_of_house": null,
"created_at": "2016-12-04 13:55:52",
"updated_at": "2017-03-08 14:03:44",
"deleted_at": null,
"both": [
{
"id": 177,
"name": "NIS",
"created_at": "2016-12-27 10:28:29",
"updated_at": "2016-12-27 10:28:29",
"pic": "http://localhost:8000/images/1482833485.jpg",
"pivot": {
"user_id": 4,
"car_id": 177,
"type": "car"
}
},
"both": [
{
"name": "Abdulaziz Alomhsen",
"age": "30",
"created_at": "2017-02-28 09:36:15",
"updated_at": "2017-03-08 08:46:06",
"status": "جايه",
"pic": "http://localhost:8000/images/1488714520.jpg",
"id": 2,
"pivot": {
"user_id": 4,
"driver_id": 2,
"type": "driver"
}
},
I want to create a object Checklist with the following JSON. But I think the Arraylist categories isn't created. I do not have an exception the debug console enter into bucle when create the object : " Background partial concurrent mark sweep GC freed 165848(5MB) AllocSpace objects, 144(1852KB) LOS objects, 22% free, 55MB/71MB, paused 5.343ms total 67.660ms "
{"type_check":"CAB","description":"simple cabin","categories":[{"category_id":"3","description":"Confort"},{"category_id":"4","description":"Servicios"},{"category_id":"5","description":"Alimentación"},{"category_id":"6","description":"Personal"},{"category_id":"7","description":"Instalaciones"}]}
And the following classes:
Checklist.class
public class Checklist {
private String type_check;
private String description;
private ArrayList<Category> categories;}
Category.class
public class Category {
private int category_id;
private String description;
}
Creating the object:
Gson gson = new GsonBuilder().create();
Checklist check = gson.fromJson(checklist.toString(), Checklist.class);
I must specify the arraylist when I parse the json?? Thanks and have a nice day.
this is how the json would look like with following code
[
{
"type_check": "CAB_0",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
},
{
"type_check": "CAB_1",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
},
{
"type_check": "CAB_2",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
},
{
"type_check": "CAB_3",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
},
{
"type_check": "CAB_4",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
},
{
"type_check": "CAB_5",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
},
{
"type_check": "CAB_6",
"description": "simple cabin",
"categories": [
{
"category_id": 0,
"description": "Description_0"
},
{
"category_id": 1,
"description": "Description_1"
},
{
"category_id": 2,
"description": "Description_2"
},
{
"category_id": 3,
"description": "Description_3"
},
{
"category_id": 4,
"description": "Description_4"
},
{
"category_id": 5,
"description": "Description_5"
},
{
"category_id": 6,
"description": "Description_6"
}
]
}
]
Checklist.Java code is here
public class Checklist {
private String type_check;
private String description;
private ArrayList<Category> categories;
public String getType_check() {
return type_check;
}
public void setType_check(String type_check) {
this.type_check = type_check;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ArrayList<Category> getCategories() {
return categories;
}
public void setCategories(ArrayList<Category> categories) {
this.categories = categories;
}
}
Category.java code is here
public class Category {
private int category_id;
private String description;
public int getCategory_id() {
return category_id;
}
public void setCategory_id(int category_id) {
this.category_id = category_id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
TestCode.Java code is here
import java.util.ArrayList;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class TestCode {
public static void main(String[] args) {
ArrayList<Checklist> list = new ArrayList<Checklist>();
list = createList();
String stringJson = (new Gson()).toJson(list);
System.out.println("##### JSON from a object #######");
System.out.println(stringJson);
System.out.println("###### Convert JSON to object ######");
ArrayList<Checklist> list2 = new ArrayList<Checklist>();
list2 = (new Gson()).fromJson(stringJson,
new TypeToken<ArrayList<Checklist>>() {
}.getType());
System.out.println("####### print out put ######");
for (int i = 0; i < list2.size(); i++) {
Checklist checklist = list2.get(i);
System.out.println(checklist.getType_check() + "");
System.out.println(checklist.getDescription() + "");
ArrayList<Category> categorys = checklist.getCategories();
for (int j = 0; j < categorys.size(); j++) {
Category category = categorys.get(j);
System.out.println(category.getCategory_id() + "");
System.out.println(category.getDescription() + "");
}
}
}
private static ArrayList<Checklist> createList() {
// TODO Auto-generated method stub
ArrayList<Checklist> list = new ArrayList<Checklist>();
for (int i = 0; i < 7; i++) {
Checklist checklist = new Checklist();
checklist.setType_check("CAB_" + i);
checklist.setDescription("simple cabin");
ArrayList<Category> categorys = new ArrayList<Category>();
for (int j = 0; j < 7; j++) {
Category category = new Category();
category.setCategory_id(j);
category.setDescription("Description_" + j);
categorys.add(category);
}
checklist.setCategories(categorys);
list.add(checklist);
}
return list;
}
}
I'm trying to deserialize some JSON data into objects for an application. Up until now it's been fine because the properties on the JSON data was static (key with a value). Now I've got a result where the key is a dynamic piece of data.
Here's an example JSON url:
http://en.wikipedia.org/w/api.php?action=query&format=json&pageids=6695&prop=info
The resulting JSON for this is:
{ "query" : { "pages" : { "6695" : { "counter" : "",
"lastrevid" : 468683764,
"length" : 8899,
"ns" : 0,
"pageid" : 6695,
"title" : "Citadel",
"touched" : "2012-01-03T19:16:16Z"
} } } }
Okay, that's great except I can't deserialize the "pages" data into an object. If I were to define a class for the pages it would have to look like this:
public class 6695
{
public string counter { get; set; }
public int lastrevid { get; set; }
public int length { get; set; }
public int ns { get; set; }
public int pageid { get; set; }
public string title { get; set; }
public string touched { get; set; }
}
In order to deserialze the contents (using JsonConvert.Deserialize(jsondata)) and we all know we can't have a class called 6695. Not only that, the name of the class would have to be different (for example pageid=7145 would have to be the 7145 class).
I can seem to pluck some values out if I use something like JObject.Parse(content) and then access items as JArrays but it's pretty ugly and I'm still stuck on trying to get out the data from the pages array.
Looking for someone to help with this. I don't think it's uncommon, it's just not JSON data I've come across before and not sure how to handle it.
Thanks!
PS forgot to mention this is on Windows Phone 7 so "dynamic" isn't available!
The simplest method. In this particular case would probably be to go dynamic.
dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(json);
var lastRevId = data.query.pages["6695"].lastrevid;
You can reference any element by it's [] name so you can do something like data["query"]["pages"]["6695"]["lastrevid"]. This will get by all those little objects where the name isn't valid in c#.
Here is how you do using https://github.com/facebook-csharp-sdk/simple-json ( https://nuget.org/packages/SimpleJson ).
var text = "{\"query\":{\"pages\":{\"6695\":{\"pageid\":6695,\"ns\":0,\"title\":\"Citadel\",\"touched\":\"2012-01-03T19:16:16Z\",\"lastrevid\":468683764,\"counter\":\"\",\"length\":8899}}}}";
(Using dynamic)
dynamic json = SimpleJson.DeserializeObject(text);
string title = json.query.pages["6695"].title;
foreach (KeyValuePair<string, dynamic> page in json.query.pages)
{
var id = page.Key;
var pageId = page.Value.pageid;
var ns = page.Value.ns;
}
(Using strongly typed classes)
class result
{
public query query { get; set; }
}
class query
{
public IDictionary<string, page> pages { get; set; }
}
class page
{
public long pageid { get; set; }
public string title { get; set; }
}
var result = SimpleJson.DeserializeObject<result>(text);
[Update]
on windows phone where dynamic is not supported and you don't want to use strongly typed classes.
var json = (IDictionary<string, object>)SimpleJson.DeserializeObject(text);
var query = (IDictionary<string, object>)json["query"];
var pages = (IDictionary<string, object>)query["pages"];
var pageKeys = pages.Keys;
var page = (IDictionary<string, object>)pages["6695"];
var title = (string)page["title"];
I hope the below example will help.
I always design a model that match the json. It is much better to work with the object when it is your own model design.
It is very easy to generate the c# model from the json. I use this website to generate the model: http://json2csharp.com
A complete example is:
C# Code:
var targetsObject = Newtonsoft.Json.JsonConvert.DeserializeObject<YourModel>(jsonString);
JSON:
{
"investors": [
{
"name": "06",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "07",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": "7.0"
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "08",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": "7.0"
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "09",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "10",
"programs": [
{
"name": "Conventional",
"value": ""
},
{
"name": "FHA - Standard",
"value": ""
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": ""
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": "2.0"
}
]
},
{
"name": "11",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "6.0"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "12",
"programs": [
{
"name": "Conventional",
"value": "3.5"
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": "5.5"
},
{
"name": "VA IRRRL",
"value": "6.0"
},
{
"name": "Non-Prime",
"value": ""
}
]
},
{
"name": "13",
"programs": [
{
"name": "Conventional",
"value": ""
},
{
"name": "FHA - Standard",
"value": "5.0"
},
{
"name": "FHA - Streamline",
"value": ""
},
{
"name": "VA",
"value": ""
},
{
"name": "VA IRRRL",
"value": ""
},
{
"name": "Non-Prime",
"value": "2.0"
}
]
}
]
}
Model:
public class Program
{
public string name { get; set; }
public string value { get; set; }
}
public class Investor
{
public string name { get; set; }
public List<Program> programs { get; set; }
}
public class RootObject
{
public List<Investor> investors { get; set; }
}
Using Json.net you can just do:
Dictionary<string,object> result = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
foreach(var item in result)
Console.WriteLine(item.Key + " " + item.Value);
How about a simple search and replace in the JSON string ? While it might not be the most elegant solution, it would possibly be the most pragmatic one.
Maybe you could just use one reserved attribute to contain the object type, and then use the base type as shown in this article: Dynamic types with JSON.NET