Android parse nested json - android

Hi guys I have a problem parsing my nested json array. This is my sample json response:
{
"SUCCESS": true,
"DATA": [
{
"ShowData": [
{
"ShowTitle": "Episode 1",
"Category": "Comedy"
},
{
"ShowTitle": "Episode 1a",
"Category": "Drama"
},
{
"ShowTitle": "Mr. Right",
"Category": "Musical"
},
{
"ShowTitle": "The Making",
"Category": "Talk"
},
{
"ShowTitle": "Presscon",
"Category": "Comedy"
},
{
"ShowTitle": "Presscon 2",
"Category": "Drama"
},
{
"ShowTitle": "Episode 2",
"Category": "Comedy"
},
{
"ShowTitle": "Episode 2",
"Category": "Drama"
}
]
}
]
}
This is what I've tried so far:
Activity:
ArrayList<HashMap<String, String>> showsList
= Parser.getShowsResponseBody(response);
ArrayList<HashMap<String, String>> result = new ArrayList<>();
Set<String> titles = new HashSet<>();
for(HashMap<String, String> map : showsList) {
if(titles.add(map.get("Category"))) {
result.add(map);
}
}
Parser:
public static List<Show> getShowsResponseBody(Response response) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(response.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
List<WorldShow> list = new ArrayList<>();
try {
JSONObject json = new JSONObject(result);
JSONArray jArray = json.getJSONArray("Data");
for (int i = 0; i < jArray.length(); i++) {
JSONObject json_data = jArray.getJSONObject(i);
JSONArray arr = json_data.getJSONArray("ShowData");
for(int j = 0; j < arr.length(); j++) {
JSONObject innerData = arr.getJSONObject(j);
Show show = new Show(); // Create Object here
show.setShowTitle(innerData.getString("ShowTitle"));
show.setCategory(innerData.getString("Category"));
list.add(show); // Finally adding the model to List
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
My expected output is:
Comedy: Episode 1, Presscon, Episode 2
Drama: Episode 1a, Presscon 2, Episode 2
Musical: Mr. Right
Talk: The Making
But when I run the app, it's displaying all the records in all category. What seem to be wrong with my code? I already used HashSet to remove duplicate objects but it's still the same. Any help would be gladly appreciated! Thanks in advance!

// Make a map to hold the mapping between categories and shows:
// (A single category is mapped to a collection of 1 or more shows)
Map<String,List<Show>> catShows = new HashMap<String,List<Show>>();
// Put a Show object into the category map for its matching category:
private void addShow( Map<String,List<Show>> map, Show show ) {
// Get the shows already stored under that category:
List<Show> list = map.get( show.getCategory() );
if ( list == null ) {
// There's no entry for that category yet, so we create a new (empty) list:
list = new ArrayList<Show>();
// Store the new list for its category:
map.put( show.getCategory(), list );
}
// Add the given show to the list for its category:
list.add( show );
}
// Example for how to iterate over the map created above:
private void process( Map<String,List<Show>> map ) {
for ( Map.Entry<String, List<Show>> e : map.entrySet() ) {
final String category = e.getKey();
final List<Show> shows = e.getValue();
// Now we have in shows the list of all shows for the category.
System.out.println( "Cat: " + category );
// Output all shows for the current category:
for ( Show s : shows ) {
System.out.println ( s.getShowTitle() );
}
}
}

I think you might change your approach.
I suggest you to use GSon Library and create a class that represents your json:
Possible scenario:
Result.class
public class Result{
boolean success;
List<Data> data;
//getter and setter
}
Data.class
public class Data{
List<Item> items;
//getter and setter
}
Item.class
public class Item{
String ShowTitle;
String Category;
//getter and setter
}
to parse json:
Gson gson = new Gson();
Result result = gson.fromJson(json, Result.class);
check this

Related

How should I parse this kind of JSON?

I'm new to JSON parsing. It would be a great help if anyone would help me with parsing this kind of json array in Android.
Thank you
{
"response": 200,
"department": [
"Information Technology"
],
"subject": [
"ads(th)"
],
"professional": [
"cg(th)",
"cg(lab)"
],
"semester": [
"3A",
"5A",
"5A"
]
}
This is ur response:
{
"response": 200,
"department": [
"Information Technology"
],
"subject": [
"ads(th)"
],
"professional": [
"cg(th)",
"cg(lab)"
],
"semester": [
"3A",
"5A",
"5A"
]
}
U can do like this
String responseString="" //this string is ur web service response
try {
//JSON is the JSON code above
JSONObject jsonResponse = new JSONObject(responseString);
JSONArray department = jsonResponse.getJSONArray("department");
String hey = department.toString();
JSONArray subject = jsonResponse.getJSONArray("subject");
String sub = subject.toString();
JSONArray professional= jsonResponse.getJSONArray("professional");
String pro = professional.toString();
//like this u can parse other JsonArray
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
After getting those values in jsonarray u want to display it in spinner than u can do like this
ArrayList<String> listdata = new ArrayList<String>();
if (professional != null) {
for (int i=0;i<professional.length();i++){
listdata.add(professional.getString(i));
}
}
For Display into spinner
Spinner spinner = (Spinner) findViewById(R.id.SpinnerSpcial);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, listdata);//Pass list data of Profession
spinner.setAdapter(adapter);
Notes:
You can make custom adapter also by extending BaseAdapter or ArrayAdapter for Spinner.
Hope this will help u ... if u have any questions u can ask
Try this,
try {
JSONObject obj_result=new JSONObject(result);
String response=obj_result.getString("response");
JSONArray arr_department=obj_result.getJSONArray("department");
for(int i=0;i<arr_department.length();i++)
{
String department_name=arr_department.getString(i);
Log.d("TAG","department_name:"+department_name);
}
JSONArray arr_subject=obj_result.getJSONArray("subject");
for(int i=0;i<arr_subject.length();i++)
{
String subject_name=arr_subject.getString(i);
Log.d("TAG","subject_name:"+subject_name);
}
JSONArray arr_professional=obj_result.getJSONArray("professional");
for(int i=0;i<arr_professional.length();i++)
{
String professional_name=arr_professional.getString(i);
Log.d("TAG","professional_name:"+professional_name);
}
JSONArray arr_semester=obj_result.getJSONArray("semester");
for(int i=0;i<arr_semester.length();i++)
{
String semester_name=arr_semester.getString(i);
Log.d("TAG","semester_name:"+semester_name);
}
} catch (JSONException e) {
e.printStackTrace();
}
try { //When parsing JSON, you need try catch to handle error if occure
JSONObject fullJSON = new JSONObject("{\"response\":200,\"department\":[\"Information Technology\"],\"subject\":[\"ads(th)\"],\"professional\":[\"cg(th)\",\"cg(lab)\"],\"semester\":[\"3A\",\"5A\",\"5A\"]}");
int response = fullJSON.getInteger("response");
JSONArray departement = fullJSON.getJSONArray("department");
Log.i("", departement.getString(0));
JSONArray semester = fullJSON.getJSONArray("semester");
for(int i=0; i<semester.length(); i++) {
Log.i("semester", semester.getString(i));
}
} catch (JSONException e) {
//here's the error message you can get from
e.printStackTrace();
}
I suggest you use Gson Libray
With Gson your mapping class will be like this:
public class YourClass {
#SerializedName("response")
private Integer response;
#SerializedName("department")
private List<String> department;
#SerializedName("subject")
private List<String> subject;
#SerializedName("professional")
private List<String> professional;
#SerializedName("semester")
private List<String> semester;
}
With Gson you can transform your Json in POJO (or vice versa) easily. Check the documentation.

Getting JSON Array values Within a JSOn Object and Use In Class Object

I am trying to populate a class object with JSON data, and I keep getting this error
org.json.JSONException: No value for machinereports
Here is the sample json file, I am trying to use
{
"id" : 1,
"reports": [
{
"id": "1",
"title": "For Reorder",
"subtitle": "Report Name",
"date": "Monday, Aug 08, 2016",
"machinereports": [
{
"name": "Reorder List",
"count": "9"
},
{
"name": "Reorder List Critical",
"count": "9"
}
]
}
]
}
Here is the code I am trying to retrieve and populate my class object with
public class Report {
public String id;
public String title;
public String subtitle;
public String date;
public ArrayList<String> machinereports = new ArrayList<>();
public static ArrayList<Report> getReportsFromFile(String filename, Context context) {
final ArrayList<Report> reportList = new ArrayList<>();
try {
// Load Data
String jsonStr = loadJsonFromAsset("reports.json", context);
JSONObject jsonOne = new JSONObject(jsonStr);
JSONArray reports = jsonOne.getJSONArray("reports");
// Get Report objects from data
for(int i = 0; i < reports.length(); i++) {
Report report = new Report();
report.id = reports.getJSONObject(i).getString("id");
report.title = reports.getJSONObject(i).getString("title");
report.subtitle = reports.getJSONObject(i).getString("subtitle");
report.date = reports.getJSONObject(i).getString("date");
// Get inner array listOrReports
JSONArray rList = jsonOne.getJSONArray("machinereports");
for(int j = 0; j < rList.length(); j++) {
JSONObject jsonTwo = rList.getJSONObject(j);
report.machinereports.add(jsonTwo.getString("reportName"));
/* report.machinereports.add(jsonTwo.getString("count"));*/
}
reportList.add(report);
}
} catch (JSONException e) {
e.printStackTrace();
}
return reportList;
}
I can't seem to figure out, where I am having the problem, when I step through, when it gets to second JSONArray object it goes to the catch exception.
Your JSON does not have a field named reportName.
report.machinereports.add(jsonTwo.getString("reportName"));
change it to
report.machinereports.add(jsonTwo.getString("name"));
Also with the answer from #comeback4you you have the wrong call to the JsonArray.
JSONArray rList = jsonOne.getJSONArray("machinereports");
Should be
JSONArray rList = reports.getJSONObject(i).getJSONArray("machinereports");
JSONArray rList = jsonOne.getJSONArray("machinereports");
change to
JSONArray rList = reports.getJSONObject(i).getJSONArray("machinereports");
and inside for loop change below
report.machinereports.add(jsonTwo.getString("name"));

Android parse json tree

I have tree JSON-structured data.
Something like
{
"result": [
{
"id": 1,
"name": "test1"
},
{
"id": 2,
"name": "test12",
"children": [
{
"id": 3,
"name": "test123",
"children": [
{
"id": 4,
"name": "test123"
}
]
}
]
}
]
}
model:
class DataEntity {
int id;
String name;
List<DataEntity> childDataEntity;
}
Parsing via org.json
List<DataEntity> categories = new ArrayList<DataEntity>();
private List<DataEntity> recursivellyParse(DataEntity entity, JSONObject object) throws JSONException {
entity.setId(object.getInt("id"));
entity.setName(object.getString("name"));
if (object.has("children")) {
JSONArray children = object.getJSONArray("children");
for (int i = 0; i < children.length(); i++) {
entity.setChildDataEntity(recursivellyParse(new DataEntity(), children.getJSONObject(i)));
categories.add(entity);
}
}
return categories;
}
call
JSONObject jsonObject = new JSONObject(JSON);
JSONArray jsonArray = jsonObject.getJSONArray("result");
for (int i = 0; i < jsonArray.length(); i++) {
recursivellyParse(new DataEntity(), jsonArray.getJSONObject(i));
}
But this way is wrong. After execution of the method List filled out same data.
How do I parse it right?
UPD: update JSON.
Here is Full Demo How to Parse json data as you want.
String JSON = "your json string";
ArrayList<DataEntity> finalResult = new ArrayList<>();
try {
JSONObject main = new JSONObject(JSON);
JSONArray result = main.getJSONArray("result");
for(int i=0;i<result.length();i++){
DataEntity dataEntity = parseObject(result.getJSONObject(i));
finalResult.add(dataEntity);
}
Log.d("DONE","Done Success");
} catch (JSONException e) {
e.printStackTrace();
}
Create One recursive function to parse object.
public DataEntity parseObject(JSONObject dataEntityObject) throws JSONException {
DataEntity dataEntity = new DataEntity();
dataEntity.id = dataEntityObject.getString("id");
dataEntity.name = dataEntityObject.getString("name");
if(dataEntityObject.has("children")){
JSONArray array = dataEntityObject.getJSONArray("children");
for(int i=0;i<array.length();i++){
JSONObject jsonObject = array.getJSONObject(i);
DataEntity temp = parseObject(jsonObject);
dataEntity.children.add(temp);
}
}
return dataEntity;
}
Model Class
public class DataEntity implements Serializable {
public String id = "";
public String name = "";
ArrayList<DataEntity> children = new ArrayList<>();}
In FinalResult Arraylist you will get all your parse data.
Ignoring that the JSON you show is invalid (i'm going to assume that's a copy/paste problem or typo), the issue is that you've declared your categories List as a member of whatever object that is.
It's continually getting added to on every call to recursivellyParse() and that data remains in the list. Each subsequent call from your loop is seeing whatever previous calls put in it.
A simple solution to this as your code is written would be to simply add a second version that clears the list:
private List<DataEntity> beginRecursivellyParse(DataEntity entity,
JSONObject object) throws JSONException {
categories.clear();
return recursivellyParse(entity, object);
}
Then call that from your loop.

Android: JSONObject only parses the final object in file

I have a json file formatted like this (only the actual file has no whitespace):
{
"main": [
{
"sections": [
"sec1",
"sec2"
],
"title": "Section List 1"
},
{
"sections": [
"sec3",
"sec4",
"sec5"
],
"title": "Section List 2"
}
],
"sections": {
"sec1": {
"products": [
"prod1",
"prod2"
]
},
"sec2": {
"products": [
"prod3"
]
}
},
"products": {
"prod1": {
"url": "url1.gif",
"title": "Product 1"
},
"prod2": {
"url": "url2.gif",
"title": "Product 2"
},
"prod3": {
"url": "url3.gif",
"title": "Product 3"
}
}
}
When I attempt to send the data for that file into JSONObject, the JSONObject being loaded only contains the final object in the top list, in this case "products". Right now, my code to load the JSONObject is this:
JSONObject dlResult = new JSONObject(new Scanner(cnxn.getInputStream()).nextLine());
I've also tried storing the data in a String first and giving that to the JSONObject constructor, I've tried giving that String to a JSONTokener first, and giving that tokener to the JSONObject constructor. Both the String and the JSONTokener contain the entire file, but once it gets put into the JSONObject, it's always the same thing - "main" and "sections" get cut out, and only "products" remains.
Here's the rest of my relevant code:
public class MapsListFragment extends ListFragment
{
private static JSONObject mDlResult;
private ArrayAdapter<MapInfo> mMapListAdapter = null;
private class MapInfo
{
private String mText;
private String mURL;
MapInfo(String inText, String inURL)
{
mText = inText;
mURL = inURL;
}
public String URL()
{
return mURL;
}
#Override
public String toString()
{
return mText;
}
}
public class MapsListUpdater extends AsyncTask<String, String, JSONObject>
{
private static final String URL = "http://jsonURL/products.json";
private Date lastUpdate;
#Override
protected JSONObject doInBackground(String... inObjects)
{
Date ifModifiedSince = lastUpdate;
try
{
HttpURLConnection cnxn = (HttpURLConnection) new URL(URL).openConnection();
if (ifModifiedSince != null)
cnxn.setIfModifiedSince(ifModifiedSince.getTime());
cnxn.connect();
if (cnxn.getResponseCode() != HttpURLConnection.HTTP_NOT_MODIFIED)
{
mDlResult = new JSONObject(new Scanner(cnxn.getInputStream()).nextLine());
}
cnxn.disconnect();
}
catch (Exception e)
{
boolean check = true;
}
return mDlResult;
}
#Override
protected void onPostExecute(JSONObject result)
{
super.onPostExecute(result);
try
{
// This is really ugly and brute-forcey, but it's the only way I could get JSONObjects populated with ALL the data!
/*String[] tryThis = mDlResult.split(",\"sections\":");
tryThis[0] += '}';
tryThis[1] = tryThis[1].substring(0, tryThis[1].indexOf("]}},\"products\":"));
tryThis[1] = "{\"sections\":" + tryThis[1] + "]}}}";*/
JSONObject mainObj = mDlResult.getJSONObject("main");//new JSONObject(mDlResult);
JSONArray mainArray = mainObj.getJSONArray("main");
Vector<String> titles = new Vector<String>();
mMapListAdapter.clear();
for (int i = 0; i < mainArray.length(); i++)
{
JSONObject object = mainArray.getJSONObject(i);
String title = object.getString("title");
if(!titles.contains(title))
{
titles.add(title);
mMapListAdapter.add(new MapInfo(object.getString("title"), null));
}
}
}
catch (Exception e)
{
boolean check = true;
}
}
}
}
I feel a little foolish now. As it turns out, the JSONObject was getting EXACTLY what I asked it for... only the objects within it were getting reordered, so I couldn't see the first 2 objects in my debugger!
Try reading it into a JSONArray and let me know how you get on:
JSONArray dlResult = new JSONArray(cnxn.getInputStream());

JSON Parsing in android - from resource folder

I've a kept one text file in res/raw folder in eclipse. I am showing here the content of that file:
{
"Categories": {
"Category": [
{
"cat_id": "3",
"cat_name": "test"
},
{
"cat_id": "4",
"cat_name": "test1"
},
{
"cat_id": "5",
"cat_name": "test2"
},
{
"cat_id": "6",
"cat_name": "test3"
}
]
}
}
I want to parse this JSON array. How can I do this?
Can anybody please help me??
Thanks in advance.
//Get Data From Text Resource File Contains Json Data.
InputStream inputStream = getResources().openRawResource(R.raw.json);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
int ctr;
try {
ctr = inputStream.read();
while (ctr != -1) {
byteArrayOutputStream.write(ctr);
ctr = inputStream.read();
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.v("Text Data", byteArrayOutputStream.toString());
try {
// Parse the data into jsonobject to get original data in form of json.
JSONObject jObject = new JSONObject(
byteArrayOutputStream.toString());
JSONObject jObjectResult = jObject.getJSONObject("Categories");
JSONArray jArray = jObjectResult.getJSONArray("Category");
String cat_Id = "";
String cat_name = "";
ArrayList<String[]> data = new ArrayList<String[]>();
for (int i = 0; i < jArray.length(); i++) {
cat_Id = jArray.getJSONObject(i).getString("cat_id");
cat_name = jArray.getJSONObject(i).getString("cat_name");
Log.v("Cat ID", cat_Id);
Log.v("Cat Name", cat_name);
data.add(new String[] { cat_Id, cat_name });
}
} catch (Exception e) {
e.printStackTrace();
}
This is your code:
String fileContent;
JSONObject jobj = new JSONObject(fileContent);
JSONObject categories = jobj.getJSONObject("Categories");
JSONArray listCategory = categories.getJSONArray("Category");
for( int i = 0; i < listCategory.length(); i++ ) {
JSONObject entry = listCategory.getJSONObject(i);
//DO STUFF
}
Android framework has a helper JsonReader in android.util package
Works like a charm, presented great example. In first block small error with absent square bracket '}':
public List readJsonStream(InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
try {
return readMessagesArray(reader);
} finally {
reader.close();
}
}
Also exists great library from google-devs GSON, which gives you possibility to map json structure straight to Java model: take a look here
Read it into a String
Create a JSONArray with the retrieved String
Use get() methods to retrieve its data

Categories

Resources