HOWTO: Processing XML with JSON

336 views
Skip to first unread message

www.gtraffic.info

unread,
Aug 19, 2006, 6:38:41 AM8/19/06
to Google Web Toolkit
I have been working on a GWT version of my site www.gtraffic.info. I
have a number of existing python scripts which download the BCC traffic
information and produce a simpler XML which the site can load and
process using AJAX. The GWT doesn't support processing XML at the
moment (though this is promised in the next version) but does provide a
number of classes in the samples which can process data in JSON format.

The purpose of this article is to describe how to take your existing
XML, convert it to JSON and then process it using the supplied Google
JSON classes.

1) This article on xml.com
(http://www.xml.com/pub/a/2006/05/31/converting-between-xml-and-json.html)
describes how to convert XML to JSON. It also provides a number of
Javascript functions to perform this here
(http://goessner.net/download/prj/jsonxml/).

Download the code for xml2json
(http://goessner.net/download/prj/jsonxml/xml2json.js). You will also
need the function 'parseXml' stated in the article. Copy this function
into the file 'xml2json.js' so it is available to you.

The javascript code should reside in the 'public' directory of your GWT
project alongside your main html files.


2) Create a class to hold a static function which is going to call the
javascript from the GWT app i.e.

public class JsonXml
{
public static native String xml2json(String xml, String tab) /*-{
var dom = $wnd.parseXml(xml);

var jsonStr = $wnd.xml2json(dom, tab);

return jsonStr;
}-*/;
}

This is just a holder class. It's the function xml2json which is
important so you can put it anywhere you want.

3) Implement the interface for ResponseTextHandler in an application
class of your choice. i.e

public class TestApplication implements ResponseTextHandler
{

/**
* This is the entry point method.
*/
public void onModuleLoad()
{
// Do async fetch
HTTPRequest.asyncGet("trafficRegion.xml", this);
}

public void onCompletion(String responseText)
{
String jsonString = JsonXml.xml2json(responseText, "");

// Process using JSON files (see further on in article)
}

}

Please note I have left out lots of surrounding code. This is just for
illustration. The file 'trafficRegion.xml' resides in the same place as
you main html files and the javascript function 'xml2json.js' i.e the
'public' directory.

That's it. You have loaded an xml file and converted it to JSON. Now
you will want to extract some data.

4) Take the JSON classes from the Google samples and pasted them into
you source tree maintaining the directory structure
(com/google/gwt/sample/json/client). You don't need the 'public'
directory or the files 'COPYING' and 'search-results.js'.

These are:

JSON.java
JSONBoolean.java
JSONException.java
JSONNumber.java
JSONObject.java
JSONParser.java
JSONString.java
JSONValue.java

Create a file called 'client.gwt.xml' in the directory
'com/google/gwt/sample/json' it should contain

<module>
<inherits name='com.google.gwt.user.User'/>
</module>

5) Still with me? Your function 'onCompletion' now looks like this:

public void onCompletion(String responseText)
{
String jsonString = JsonXml.xml2json(responseText, "");

JSONObject jsonObject = null;

try
{
jsonObject = JSONParser.parse(jsonString);
}
catch (JSONException e)
{
String err = e.toString();
}

if (jsonObject != null)
{
processData(jsonObject);
}
}

I haven't done anything with the error string but you can put up and
alert if you are getting errors.

6) The function processData is going to extract information from the
JSON. You will need the following function modified from the original
JSON code.

public JSONValue getJSONElementByTagName(String name, JSONValue
jsonValue)
{
JSONObject jsonObject = null;
JSONValue value = null;

if ((jsonObject = jsonValue.isObject()) != null)
{
String[] keys = jsonObject.getKeys();

int i = 0; boolean found = false;
while (i<keys.length&&!found)
{
String key = keys[i];
if (key.equals(name))
{
value = jsonObject.get(key);
found = true;
}
else
i++;
}

// Drill down into data
if (!found)
{
i = 0; found = false;
while (i<keys.length&&!found)
{
String key = keys[i];
value = getJSONElementByTagName(name,
jsonObject.get(key));
if (value!=null)
{
found = true;
}
}
}
}

return (value);
}

Lets get some data. My xml file looks like this:

<?xml version="1.0"?><?xml-stylesheet type="text/xsl"
href="panelmenu.xsl"?>
<page>
<title>Regional Data</title>
<center lat="54.32933804825251" lng="-3.955078125"/>
<location id="1" url="data/northamptonshire.xml">
<point lat="52.2859278" lng="-0.845080333333"/>
<icon image="icon/regionMarker.png"/>

<summary class="regionSummary" >
<title>Northamptonshire</title>
<icon image="icon/regionPanel.png"/>
<line>Northamptonshire [15]</line>
</summary>

<content>
</content>
</location>
</page>

We will extract the title and the centre (lat) and (lng)

void processData(JSONValue jsonValue)
{

JSONValue page = getJSONElementByTagName("page", jsonValue);

if (page!=null)
{
JSONValue title = getJSONElementByTagName("title", page);

if (title.toString().equals(TXT_REGIONAL_DATA))
{
JSONValue centre = getJSONElementByTagName("center", page);
if (centre!=null)
{
String centreLng = "";
String centreLat = "";

JSONValue lng = getJSONElementByTagName("@lng",
centre);
if (lng!=null) centreLng = lng.toString();

JSONValue lat = getJSONElementByTagName("@lat",
centre);
if (lat!=null) centreLat = lat.toString();
}

// Do something with centre point
}
}
}

And so on, drilling down into the data.

I hope this is of use to some of you. Of course Google might release
the new version of GWT tomorrow and this will all be redundant.

There is a copy of this article at www.netthreads.co.uk.

www.gtraffic.info

www.gtraffic.info

unread,
Aug 19, 2006, 7:39:47 AM8/19/06
to Google Web Toolkit
Oops. Missed a bit out.

After step 4) do the following:

Copy the line

<inherits name='com.google.gwt.sample.json.client'/>

into your MyApplication.gwt.xml file where 'MyApplication' is the name
of you main application.

You should now be able to use the google JSON classes in your own code.

Al.
www.gtraffic.info

Adam T

unread,
Aug 19, 2006, 12:36:28 PM8/19/06
to Google Web Toolkit
Hi,

Looks really interesting, and an interesting app too (funny to see that
Bristol is still a hell hole of roadworks years after I moved from
there)!

However I'm wondering why you didn't use the GWT XML support. I've not
used it yet but will soon and was wondering if it came out too late for
you (your post is 19th and XML support came in on 11th August) or if
you've had problems with it?

www.gtraffic.info

unread,
Aug 19, 2006, 4:19:44 PM8/19/06
to Google Web Toolkit
Yes quite right. I have had this code kicking around for wee while now.
I have just got round to looking at again and thought I'd post an
article about it. I haven't checked in to see what the latest version
of the GWT was. I see I am going to have to download it and try it out.

There are two things here which people might find useful.

- how to include Googles sample code into your own app.
- the 'getJSONElementByTagName'.

Al.
www.gtraffic.info

Reply all
Reply to author
Forward
0 new messages