JSON
Parsing
JSON
(JavaScript Object Notation) is a lightweight data-interchange
format. It is easy for humans to read and write. It is easy for
machines to parse and generate. It is based on a subset of the
JavaScript
Programming Language,
Standard
ECMA-262 3rd Edition - December 1999.
JSON is a text format that is completely language independent but
uses conventions that are familiar to programmers of the C-family of
languages, including C, C++, C#, Java, JavaScript, Perl, Python, and
many others. These properties make JSON an ideal data-interchange
language.
JSON is built on two structures:
A collection of name/value pairs.
In various languages, this is realized as an object, record,
struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is
realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern
programming languages support them in one form or another. It makes
sense that a data format that is interchangeable with programming
languages also be based on these structures.
In JSON, they take on these forms:
An
object is an unordered set of name/value pairs. An
object begins with
{ (left
brace) and ends with
} (right
brace). Each name is followed by
: (colon)
and the name/value pairs are separated by
, (comma).
An
array is an ordered collection of values. An array
begins with
[ (left
bracket) and ends with
] (right
bracket). Values are separated by
, (comma).
A
value can be a
string in double quotes, or a
number, or
true or
false
or
null, or an
object or an
array.
These structures can be nested.
A
string is a sequence of zero or more Unicode characters,
wrapped in double quotes, using backslash escapes. A character is
represented as a single character string. A string is very much like
a C or Java string.
A
number is very much like a C or Java number, except that
the octal and hexadecimal formats are not used.
Whitespace can be inserted between any pair of tokens. Excepting a
few encoding details, that completely describes the language.
What
is JSON?
JSON stands for "JavaScript Object Notation" and is
pronounced "Jason" (like in the Friday the 13th movies).
It's meant to be a human-readable and compact solution to represent a
complex data structure and facilitate data-interchange between
systems.
Why use JSON?
There are tons of reasons why you would want to use JSON:
It's human readable... if it's
properly formatted :-P
It's compact because it doesn't
use a full markup structure, unlike XML
It's easy to parse, especially in
JavaScript
A gazillion JSON libraries are
available for most programming languagues
- The data structure is easy to understand even if you're an
idiot
The JSON format
There are just a few rules that you need to remember:
Objects are encapsulated within
opening and closing brackets { }
An empty object can be represented
by { }
Arrays are encapsulated within
opening and closing square brackets [ ]
An empty array can be represented
by [ ]
A member is represented by a
key-value pair
The key of a member should be
contained in double quotes. (JavaScript does not require this.
JavaScript and some parsers will tolerate single-quotes)
Each member should have a unique
key within an object structure
The value of a member must be
contained in double quotes if it's a string (JavaScript and some
parsers will tolerates single-quotes)
Boolean values are represented
using the true or false literals in lower case
Number values are represented
using double-precision floating-point format. Scientific notation is
supported
Numbers should not have leading
zeroes
"Offensive""
characters in a string need to be escaped using the backslash
character
Null values are represented by the
null literal in lower case
Other object types, such as dates,
are not properly supported and should be converted to strings. It
becomes the responsability of the parser/client to manage this.
Each member of an object or each
array value must be followed by a comma if it's not the last one
The common extension for json
files is '.json'
- The mime type for json files is 'application/json'
Example:
{
"anObject":
{
"numericProperty":
-122,
"stringProperty":
"An offensive \" is problematic",
"nullProperty":
null,
"booleanProperty":
true,
"dateProperty":
"2011-09-23"
},
"arrayOfObjects":
[
{
"item":
1
},
{
"item":
2
},
{
"item":
3
}
],
"arrayOfIntegers":
[
1,
2,
3,
4,
5
]
}
JSON in JavaScript
Because JSON derives from JavaScript, you can parse a JSON string
simply by invoking the eval() function. The JSON string needs to be
wrapped by parenthesis, else it will not work! This is the #1 problem
when programmers first start to manipulate JSON strings.
Example:
<script
type="text/language">
// A
valid json string
var someJsonString =
'{"someProperty":"someValue"}';
//
jsonObject will contain a valid JavaScript object
var
jsonObject = eval('(' + someJsonString +
')');
// Will display the
string 'someValue'
alert(jsonObject.someProperty);
</script>
You can create JavaScript objects using the JSON syntax directly
in your code.
Example:
<script
type="text/language">
//
jsonObject is a valid JavaScript object that can be used on the
fly
var jsonObject = { someProperty :
"someValue" };
// Will display the
string 'someValue'
alert(jsonObject.someProperty);
</script>
JSON Parsing in android
Let’s look at how to parse JSON objects in android
1> First we’ll need an example :
Lets look at a standard example from the json site
http://json.org/example.html
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
you could either save this in a file or save it in a string…..like
I’ve done
2> Android already contains the required JSON libraries
Lets create a JSON Object;
private JSONObject jObject;
and lets our example be a String ,
private String jString = "{\"menu\": {\"id\": \"file\", \"value\": \"File\", \"popup\": { \"menuitem\":
[ {\"value\": \"New\", \"onclick\":
\"CreateNewDoc()\"},
{\"value\": \"Open\", \"onclick\": \"OpenDoc()\"},
{\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}]}}}";
now we have to convert jString to the jObject ,
jObject = new JSONObject(jString);
Now we have to start extracting the content from jObject ,
Lets extract the menu object by creating a new menu object,
JSONObject menuObject = jObject.getJSONObject("menu");
Now lets extract its atrtibutes ,
String attributeId = menuObject.getString("id");
String attributeValue = menuObject.getString("value");
JSONObject popupObject = menuObject.getJSONObject("popup");
since “popup” is not plainly a String lets extract it to an
object ,
3> Now popup contains an array of “menuitem”
So, we’ll have to extract it to a JSONArray,
JSONArray menuitemArray = popupObject.getJSONArray("menuitem");
Since it contains 3 items lets put it in a for loop.
for (int i = 0; i < 3; i++) {
System.out.println(menuitemArray.getJSONObject(i)
.getString("value").toString());
System.out.println(menuitemArray.getJSONObject(i).getString(
"onclick").toString());
}
Basically thats it , u should see the output in the DDMS
4> The full code is as below,
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
public class JsonParser extends Activity {
private JSONObject jObject;
private String jString = "{\"menu\": {\"id\": \"file\", \"value\": \"File\", \"popup\": { \"menuitem\":
[ {\"value\": \"New\",
\"onclick\":
\"CreateNewDoc()\"},
{\"value\": \"Open\", \"onclick\": \"OpenDoc()\"}, {\"value\": \"Close\", \"onclick\": \"CloseDoc()\"}]}}}";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
parse();
} catch (Exception e) {
e.printStackTrace();
}
}
private void parse() throws Exception {
jObject = new JSONObject(jString);
JSONObject menuObject = jObject.getJSONObject("menu");
String attributeId = menuObject.getString("id");
System.out.println(attributeId);
String attributeValue = menuObject.getString("value");
System.out.println(attributeValue);
JSONObject popupObject = menuObject.getJSONObject("popup");
JSONArray menuitemArray = popupObject.getJSONArray("menuitem");
for (int i = 0; i < 3; i++) {
System.out.println(menuitemArray.getJSONObject(i)
.getString("value").toString());
System.out.println(menuitemArray.getJSONObject(i).getString(
"onclick").toString());
}
}
}
Problem:
How to parse JSON response?
Solution:
Many times we get JSON
string as a response from web server, now we have to parse the JSON
string into either array, objects or values to display the response
in the particular views like ListView, TextView, etc.
We can use
JSONObject
and
JSONArray
for parsing the response string.
Now, consider this
sample
JSON response string for the understanding of parsing
example:
view
plaincopy to clipboardprint?
{"FirstObject": { "attr1":"one value" ,"attr2":"two value",
"sub": { "sub1":[ {"sub1_attr":"sub1_attr_value" },{"sub1_attr":"sub2_attr_value" }]}
}
- }
And it looks as below in FireBug tool:
Android JSON Parsing example
Now, let me start to give step by step demo for parsing the same
JSON resoponse:
Step – 1:
create
a JSONObject with the received response string:
view
plaincopy to clipboardprint?
- JSONObject jsonObject = new JSONObject(strJSONResponse);
Step – 2:
Get the main object from the created json object by using
getJSONObject()
method:
view
plaincopy to clipboardprint?
- JSONObject object = jsonObject.getJSONObject("FirstObject");
Step – 3:
Now
this FirstObject contains 2 strings namely “attr1″,”attr2″
and a object namely “sub”.
So get 2 strings by using
getString()
method.
view
plaincopy to clipboardprint?
String attr1 = object.getString("attr1");
- String attr2 = object.getString("attr2");
and get a sub object by using the same getJSONObject() method as
we have used above:
JSONObject subObject = object.getJSONObject("sub");
Step – 4:
Now this “sub” sub-object contains 1 array namely “sub1″.
So we can get this JSON array by using
getJSONArray()
method:
view
plaincopy to clipboardprint?
- JSONArray subArray = subObject.getJSONArray("sub1");
Now, we just need to process this array same as simple string
array:
view
plaincopy to clipboardprint?
for(int i=0; i<subArray.length(); i++)
{
strParsedValue+="\n"+subArray.getJSONObject(i).getString("sub1_attr").toString();
- }
This is complete now. Enjoy
Output
Snapshot:
Android - JSON Parsing tutorial
Full source
code:
view
plaincopy to clipboardprint?
package com.technotalkative.jsonparsing;
import org.json.JSONArray;
mport org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
/**
*
* Demo of JSON Parsing
* @author Paresh N. Mayani
* http://www.technotalkative.com/android-json-parsing/
*
*/
public class JSONParsingActivity extends Activity {
/** Called when the activity is first created. */
TextView txtViewParsedValue;
private JSONObject jsonObject;
String strParsedValue = null;
private String strJSONValue = "{\"FirstObject\":{\"attr1\":\"one value\" ,\"attr2\":\"two value\","
+"\"sub\": { \"sub1\":[ {\"sub1_attr\":\"sub1_attr_value\" },{\"sub1_attr\":\"sub2_attr_value\" }]}}}";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtViewParsedValue = (TextView) findViewById(R.id.textView1);
try {
parseJSON();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void parseJSON() throws JSONException
{
jsonObject = new JSONObject(strJSONValue);
//parsing Object value
JSONObject object = jsonObject.getJSONObject("FirstObject");
String attr1 = object.getString("attr1");
String attr2 = object.getString("attr2");
strParsedValue="Attribute 1 value => "+attr1;
strParsedValue+="\n Attribute 2 value => "+attr2;
//parsing sub-object
JSONObject subObject = object.getJSONObject("sub");
// parsing array values
JSONArray subArray = subObject.getJSONArray("sub1");
strParsedValue+="\n Array Length => "+subArray.length();
for(int i=0; i<subArray.length(); i++)
{
strParsedValue+="\n"+subArray.getJSONObject(i).getString("sub1_attr").toString();
}
txtViewParsedValue.setText(strParsedValue);
}
}
// Actual JSON Value
/*
{"FirstObject": { "attr1":"one value" ,"attr2":"two value",
"sub": { "sub1":[ {"sub1_attr":"sub1_attr_value" },{"sub1_attr":"sub2_attr_value" }]}
}
}; */
// Same JSON value in XML
/*
<FirstObject obj1="Object 1 value" obj2="Object 2 value">
<sub>
<sub1 sub1_attr="sub1_attr_value" />
<sub1 sub1_attr="sub2_attr_value" />
</sub>
- </FirstObject> */
Example
Program
SingleMenuItemActivity.java
package
com.androidhive.jsonparsing;
import
android.app.Activity;
import
android.content.Intent;
import
android.os.Bundle;
import
android.widget.TextView;
public
class SingleMenuItemActivity extends Activity {
//
JSON node keys
private
static final String TAG_NAME = "name";
private
static final String TAG_EMAIL = "email";
private
static final String TAG_PHONE_MOBILE = "mobile";
@Override
public
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.single_list_item);
//
getting intent data
Intent
in = getIntent();
//
Get JSON values from previous intent
String
name = in.getStringExtra(TAG_NAME);
String
cost = in.getStringExtra(TAG_EMAIL);
String
description = in.getStringExtra(TAG_PHONE_MOBILE);
//
Displaying all values on the screen
TextView
lblName = (TextView) findViewById(R.id.name_label);
TextView
lblCost = (TextView) findViewById(R.id.email_label);
TextView
lblDesc = (TextView) findViewById(R.id.mobile_label);
lblName.setText(name);
lblCost.setText(cost);
lblDesc.setText(description);
}
}
JSONParser.java
package
com.androidhive.jsonparsing;
import
java.io.BufferedReader;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.InputStreamReader;
import
java.io.UnsupportedEncodingException;
import
org.apache.http.HttpEntity;
import
org.apache.http.HttpResponse;
import
org.apache.http.client.ClientProtocolException;
import
org.apache.http.client.methods.HttpPost;
import
org.apache.http.impl.client.DefaultHttpClient;
import
org.json.JSONException;
import
org.json.JSONObject;
import
android.util.Log;
public
class JSONParser {
static
InputStream is = null;
static
JSONObject jObj = null;
static
String json = "";
//
constructor
public
JSONParser() {
}
public
JSONObject getJSONFromUrl(String url) {
//
Making HTTP request
try
{
//
defaultHttpClient
DefaultHttpClient
httpClient = new DefaultHttpClient();
HttpPost
httpPost = new HttpPost(url);
HttpResponse
httpResponse = httpClient.execute(httpPost);
HttpEntity
httpEntity = httpResponse.getEntity();
is
= httpEntity.getContent();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
try
{
BufferedReader
reader = new BufferedReader(new InputStreamReader(
is,
"iso-8859-1"), 8);
StringBuilder
sb = new StringBuilder();
String
line = null;
while
((line = reader.readLine()) != null) {
sb.append(line
+ "\n");
}
is.close();
json
= sb.toString();
}
catch (Exception e) {
Log.e("Buffer
Error", "Error converting result " + e.toString());
}
//
try parse the string to a JSON object
try
{
jObj
= new JSONObject(json);
}
catch (JSONException e) {
Log.e("JSON
Parser", "Error parsing data " + e.toString());
}
//
return JSON String
return
jObj;
}
}
AndroidJSONParsingActivity
package
com.androidhive.jsonparsing;
import
java.util.ArrayList;
import
java.util.HashMap;
import
org.json.JSONArray;
import
org.json.JSONException;
import
org.json.JSONObject;
import
android.app.ListActivity;
import
android.content.Intent;
import
android.os.Bundle;
import
android.util.Log;
import
android.view.View;
import
android.widget.AdapterView;
import
android.widget.AdapterView.OnItemClickListener;
import
android.widget.ListAdapter;
import
android.widget.ListView;
import
android.widget.SimpleAdapter;
import
android.widget.TextView;
public
class AndroidJSONParsingActivity extends ListActivity {
//
url to make request
private
static String url = "http://api.androidhive.info/contacts/";
//
JSON Node names
private
static final String TAG_CONTACTS = "contacts";
private
static final String TAG_ID = "id";
private
static final String TAG_NAME = "name";
private
static final String TAG_EMAIL = "email";
private
static final String TAG_ADDRESS = "address";
private
static final String TAG_GENDER = "gender";
private
static final String TAG_PHONE = "phone";
private
static final String TAG_PHONE_MOBILE = "mobile";
private
static final String TAG_PHONE_HOME = "home";
private
static final String TAG_PHONE_OFFICE = "office";
//
contacts JSONArray
JSONArray
contacts = null;
@Override
public
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//
Hashmap for ListView
ArrayList<HashMap<String,
String>> contactList = new ArrayList<HashMap<String,
String>>();
//
Creating JSON Parser instance
JSONParser
jParser = new JSONParser();
//
getting JSON string from URL
JSONObject
json = jParser.getJSONFromUrl(url);
try
{
//
Getting Array of Contacts
contacts
= json.getJSONArray(TAG_CONTACTS);
//
looping through All Contacts
for(int
i = 0; i < contacts.length(); i++){
JSONObject
c = contacts.getJSONObject(i);
//
Storing each json item in variable
String
id = c.getString(TAG_ID);
String
name = c.getString(TAG_NAME);
String
email = c.getString(TAG_EMAIL);
String
address = c.getString(TAG_ADDRESS);
String
gender = c.getString(TAG_GENDER);
//
Phone number is agin JSON Object
JSONObject
phone = c.getJSONObject(TAG_PHONE);
String
mobile = phone.getString(TAG_PHONE_MOBILE);
String
home = phone.getString(TAG_PHONE_HOME);
String
office = phone.getString(TAG_PHONE_OFFICE);
//
creating new HashMap
HashMap<String,
String> map = new HashMap<String, String>();
//
adding each child node to HashMap key => value
map.put(TAG_ID,
id);
map.put(TAG_NAME,
name);
map.put(TAG_EMAIL,
email);
map.put(TAG_PHONE_MOBILE,
mobile);
//
adding HashList to ArrayList
contactList.add(map);
}
}
catch (JSONException e) {
e.printStackTrace();
}
/**
* Updating parsed JSON data into ListView
* */
ListAdapter
adapter = new SimpleAdapter(this, contactList,
R.layout.list_item,
new
String[] { TAG_NAME, TAG_EMAIL, TAG_PHONE_MOBILE }, new int[] {
R.id.name,
R.id.email, R.id.mobile });
setListAdapter(adapter);
//
selecting single ListView item
ListView
lv = getListView();
//
Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new
OnItemClickListener() {
@Override
public
void onItemClick(AdapterView<?> parent, View view,
int
position, long id) {
//
getting values from selected ListItem
String
name = ((TextView)
view.findViewById(R.id.name)).getText().toString();
String
cost = ((TextView)
view.findViewById(R.id.email)).getText().toString();
String
description = ((TextView)
view.findViewById(R.id.mobile)).getText().toString();
//
Starting new intent
Intent
in = new Intent(getApplicationContext(),
SingleMenuItemActivity.class);
in.putExtra(TAG_NAME,
name);
in.putExtra(TAG_EMAIL,
cost);
in.putExtra(TAG_PHONE_MOBILE,
description);
startActivity(in);
}
});
}
}
list_item.xml
<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--
Name Label -->
<TextView
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#43bd00"
android:textSize="16sp"
android:textStyle="bold"
android:paddingTop="6dip"
android:paddingBottom="2dip"
/>
<!--
Description label -->
<TextView
android:id="@+id/email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#acacac"
android:paddingBottom="2dip">
</TextView>
<!--
Linear layout for cost and price Cost: Rs.100 -->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!--
Cost Label -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#5d5d5d"
android:gravity="left"
android:textStyle="bold"
android:text="Mobile:
" >
</TextView>
<!--
Price Label -->
<TextView
android:id="@+id/mobile"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#acacac"
android:textStyle="bold"
android:gravity="left">
</TextView>
</LinearLayout>
</LinearLayout>
</LinearLayout>
main.xml
<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!--
Main ListView
Always give id value as list(@android:id/list)
-->
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
singe_list_item.xml
<?xml
version="1.0"
encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--
Name Label -->
<TextView
android:id="@+id/name_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25dip"
android:textStyle="bold"
android:paddingTop="10dip"
android:paddingBottom="10dip"
android:textColor="#43bd00"/>
<!--
Description Label -->
<TextView
android:id="@+id/email_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#acacac"/>
<!--
Price Label -->
<TextView
android:id="@+id/mobile_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"/>
</LinearLayout>
AndroidManifest.xml
<?xml
version="1.0"
encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.androidhive.jsonparsing"
android:versionCode="1"
android:versionName="1.0"
>
<uses-sdk
android:minSdkVersion="8"
/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
>
<activity
android:label="@string/app_name"
android:name=".AndroidJSONParsingActivity"
>
<intent-filter
>
<action
android:name="android.intent.action.MAIN"
/>
<category
android:name="android.intent.category.LAUNCHER"
/>
</intent-filter>
</activity>
<!--
Single List Item View -->
<activity
android:label="Single
Menu Item"
android:name=".SingleMenuItemActivity"
>
</activity>
</application>
<uses-permission
android:name="android.permission.INTERNET"
/>
</manifest>
http:/json.org
http://www.androidcompetencycenter.com/2009/10/json-parsing-in-android/