简体   繁体   中英

Trouble parsing through complicated json

I have a json structure that looks like this:

http://pastebin.com/d6Dc1Fj9

My json parsing looks like this, edited from a tutorial so its a little dirty but I will clean it up once I figure out how this works. I am a bit lost on parsing json when there is one json object with an array of more json objects.

private class ReadJSONResult extends AsyncTask
        <String, Void, String> {
            protected String doInBackground(String... urls) {
                return readJSONFeed(urls[0]);
            }

            protected void onPostExecute(String result) {
                try {
                    Log.d("asycTask", "[ Gets into asyc task ]");
                    ///get 
                    Log.d("search", "[ check if we get search results ]");
                    Log.d("search", "[" + result + "]");

                    JSONObject jsonObject = new JSONObject(result);
                    JSONObject weatherObservationItems = 
                        new JSONObject(jsonObject.getString("JSON"));

                    Toast.makeText(getBaseContext(), 
                        weatherObservationItems.getString("totalResults"), 
                     Toast.LENGTH_SHORT).show();


                } catch (Exception e) {
                    Log.d("ReadWeatherJSONFeedTask", e.getLocalizedMessage());
                }          
            }
        }

        //gets the json from the inputed url
        public String readJSONFeed(String URL) {
            StringBuilder stringBuilder = new StringBuilder();
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(URL);
            try {
                HttpResponse response = httpClient.execute(httpGet);
                StatusLine statusLine = response.getStatusLine();
                int statusCode = statusLine.getStatusCode();
                if (statusCode == 200) {
                    HttpEntity entity = response.getEntity();
                    InputStream inputStream = entity.getContent();
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(inputStream));
                    String line;
                    while ((line = reader.readLine()) != null) {
                        stringBuilder.append(line);
                    }
                    inputStream.close();
                } else {
                    Log.d("JSON", "Failed to download file");
                }
            } catch (Exception e) {
                Log.d("readJSONFeed", e.getLocalizedMessage());
            }        
            return stringBuilder.toString();
        }

I know I am getting json results because from my log had it print the results variable and I did get my json.

Update:

Looking at my log confuses me even more. WHen I print results variable I get this

06-13 14:56:00.533: D/asycTask(19191): [ Gets into asyc task ]
06-13 14:56:00.533: D/search(19191): [ check if we get search results ]
06-13 14:56:00.541: D/search(19191): [{"currentPage":1,"numberOfPages":1,"totalResults":8,"data":[{"id":"YAKFea","name":"90 Shilling","description":"We introduced 90 Shilling, our flagship beer, at our opening party in 1989. For a while, we\u2019d been wondering what would happen if we lightened up the traditional Scottish ale? The result is an irresistibly smooth and delicious medium-bodied amber ale. The name 90 Shilling comes from the Scottish method of taxing beer. Only the highest quality beers were taxed 90 Shillings. A shilling was a British coin used from 1549 to 1982. We think you\u2019ll find this original ale brilliantly refreshing, and worth every shilling.","abv":"5.3","ibu":"27","glasswareId":4,"availableId":1,"styleId":9,"isOrganic":"N","labels":{"icon":"http:\/\/s3.amazonaws.com\/brewerydbapi\/beer\/YAKFea\/upload_1CxY2l-icon.png","medium":"http:\/\/s3.amazonaws.com\/brewerydbapi\/beer\/YAKFea\/upload_1CxY2l-medium.png","large":"http:\/\/s3.amazonaws.com\/brewerydbapi\/beer\/YAKFea\/upload_1CxY2l-large.png"},"status":"verified","statusDisplay":"Verified","createDate":"2012-01-03 02:42:38","updateDate":"2012-03-22 13:04:31","glass":{"id":4,"name":"Pilsner","createDate":"2012-01-03 02:41:33"},"available":{"id":"1","name":"Year Round","description":"Available year round as a staple beer."},"style":{"id":9,"categoryId":1,"category":{"id":1,"name":"British Origin Ales","createDate":"2012-03-21 20:06:45"},"name":"Scottish-Style Export Ale","description":"The overriding character of Scottish export ale is sweet, caramel-like, and malty. Its bitterness is perceived as low to medium. Hop flavor or aroma should not be perceived. It has medium body. Fruity-ester character may be apparent. Yeast characters such as diacetyl (butterscotch) and sulfuriness are acceptable at very low levels. The color will range from golden amber to deep brown. Bottled versions of this traditional draft beer may contain higher amounts of carbon dioxide than is typical for mildly carbonated draft versions. Chill haze is acceptable at low temperatures. Though there is little evidence suggesting that traditionally made Scottish-style export ales exhibited peat smoke character, the current marketplace offers many Scottish-style export ales with peat or smoke character present at low to medium levels. Thus a peaty\/smoky character may be evident at low to medium levels (ales with medium-high or higher smoke character would be considered a smoke flavored beer and considered in another category). Scottish-style export ales may be split into two subcategories: Traditional (no smoke character) and Peated (low level of peat smoke character).","ibuMin":"15","ibuMax":"25","abvMin":"4","abvMax":"5.3","srmMin":"10","srmMax":"19","ogMin":"1.04","fgMin":"1.01","fgMax":"1.018","createDate":"2012-03-21 20:06:45"},"breweries":[{"id":"rQkKIB","name":"Odell Brewing Company","description":"We love beer. We talk about beer. We dream about beer. And we make incredible beer. We don't mess around with serving food, making music or cutting up limes to mask our beer's flavor. Our dreams lead us to create imaginative, big, bold and beautiful beers. Every ounce of our passion is poured directly into the next bottle you open. Our mission is simple; to make consistently great beer.\r\n\r\nHandcrafted classics and small batch experimental beers that include Pale Ales, Stouts, Pilsners and Porters. Come visit us in our tap room for a taste of how we keep the craft in craft beer.","website":"http:\/\/odellbrewing.com\/","established":"1989","isOrganic":"N","images":{"icon":"http:\/\/s3.amazonaws.com\/brewerydbapi\/brewery\/rQkKIB\/upload_DXbWkA-icon.png","medium":"http:\/\/s3.amazonaws.com\/brewerydbapi\/brewery\/rQkKIB\/upload_DXbWkA-medium.png","large":"http:\/\/s3.amazonaws.com\/brewerydbapi\/brewery\/rQkKIB\/upload_DXbWkA-large.png"},"status":"verified","statusDisplay":"Verified","createDate":"2012-01-03 02:42:04","updateDate":"2012-03-27 01:06:32","locations":[{"id":"Q4eTmd","name":"Main Brewery","streetAddress":"800 East Lincoln Avenue","locality":"Fort Collins","region":"C

But then it looks like it fails the try catch because it prints this line next in the log:

06-13 14:56:00.580: D/ReadWeatherJSONFeedTask(19191): No value for JSON

The error is telling you that there is no value for JSON . This is because of this line:

JSONObject weatherObservationItems = new JSONObject(jsonObject.getString("JSON"));

Basically, you need to use the propery key when selecting a property from the JSON object. It looks like the key you want to use to get your weather items is "data" and that will be a JSONArray. You can instead create it, something like:

JSONArray weatherObservationItems = jsonObject.getJSONArray("data");

Then you can iterate through that JSONArray to see the totalResults property that you are trying to query.

To iterate through the times in the array, simply loop over it and pull out each JSONObject. For example:

for(int i = 0; i < weatherObservationItems.length(); i++) {
    JSONObject item = weatherObservationItems.getJSONIbject(i);
    String name = item.getString("name");
    String desc = item.getString("description");
    // etc etc
}

This line will throw an error because your JSON does not have an attribute with the name 'JSON':

 JSONObject weatherObservationItems = 
                        new JSONObject(jsonObject.getString("JSON"));

Beyond that, it is quite confusing to see what you are trying to achieve. I would also recommend using Gson as posted by elf_zwölf.

While Gson is a good library, you actually don't need it. Android comes with the org.json library built in!! For starters, the documentation here will be a very helpful reference tool if you're just learning JSON parsing.

Oftentimes, creating a model like was demonstrated in the previously posted tutorial can be burdensome and way too much work for the effort. Using the org.json library, you can chain together your get methods, like so:

JSONObject json = new JSONObject(what you put in pastebin);
String string = json.getJSONArray('data')
                    .getJSONObject(0)
                    .getString("name");

And traverse the json in that manner. Json Objects are basically just big nested sets of arrays and key-value pairs. if it is a JSONObject, the parameter you pass to the get method is the key; if it is a JSONArray, you pass in the index! Using the typed getMethods and chaining as I demonstrated here also helps clean up the code a lot!

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM