Convert Xml to JSON Object in Android

Convert XML to JSON object in Android

You can try this way as well. I have tried and tested it myself.

Step 1 : Please Download the java-json.jar

Step 2: Add this to /libs folder of your project then add to build path.

Step 3: Then use it as follows

  • Imports to look for

    import org.json.JSONException;
    import org.json.JSONObject;
    import org.json.XML;
  • Sample string

    String sampleXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
    + "<mobilegate>"
    +"<timestamp>232423423423</timestamp>"
    + "<txn>" + "Transaction" + "</txn>"
    + "<amt>" + 0 + "</amt>"
    + "</mobilegate>";
  • Json String

    JSONObject jsonObj = null;
    try {
    jsonObj = XML.toJSONObject(sampleXml);
    } catch (JSONException e) {
    Log.e("JSON exception", e.getMessage());
    e.printStackTrace();
    }

    Log.d("XML", sampleXml);

    Log.d("JSON", jsonObj.toString());

Output:

XML:

<?xml version="1.0" encoding="utf-8"?><mobilegate><timestamp>232423423423</timestamp><txn>Transaction</txn><amt>0</amt></mobilegate>

JSON :

{"mobilegate":{"timestamp":232423423423,"amt":0,"txn":"Transaction"}}

Android - Parse XML to JSON

You will need to add this converter factory to your Retrofit Builder -

Retrofit.Builder()
.addConverterFactory(SimpleXmlConverterFactory.create())

This allows Retrofit to interpret the XML that it is fetching to be converted to it's equivalent JSON Data Object.

How to convert an XML structured-like object to a JSON string in Java?

So to convert it to a JSON string in an iterative way I did a preorder traversal with some modification/adjustments.

Firstly a created a help class, let's call it Node, that was used for traversing the structures. So each Element would be wrapped in such class. This class helped me to mark the nodes with certain values and to group the elements with the same name, more on this later.

The next thing was to use two data structures, a Set and a Stack (or Deque). The Set was used to keep track on the visisted/traversed nodes and the Stack was used for the traversal (the next node to traverse to in the next iteration).

Then I wrapped the root element as a Node and pushed it to the stack and the preorder traversal could begin (actually, I also added an opening { before starting the traversal). In each iteration, the child elements were "grouped" and wrapped as nodes and then pushed to the stack. With "grouped" I mean that if there was more than one child element with the same name, they were put in a list in the Node and the node was marked as a list.

After the child elements had been pushed into the stack I did the following things:

  1. If the currently visisted node is not marked as being a part of a list, I appended: <name of the node/element> : to the JSON string result. This is because if it was a part of a list, then the name should not be printed out for each node since the name should only be printed out once in beginning for arrays in JSONs, e.g: "array":[{...},..,{...}].
  2. If the currently visited node is not a list, I appended { to the result and also appended the fields/attributes if there were any.
  3. Else, if the currently visited node is a list, I appended [ and wrapped each of its grouped child elements as Nodes, marked them as being a part of a list, and pushed them to the stack (marking them this way helped in the next iterations in step 1.).
  4. Add the currently visisted node to the Set.

What about the closing parentheses? In the beginning of each iteration I used the Set to check if the currently (topmost/peek) node had already been visited (see step 4 above), if it had it could only mean one thing: it's time to close and pop the stack. If the node was marked as a list, we would close it with ], otherwise with }. Then, if the next node (peek) is not visited, it means we are moving "sideways" and should append , to the result. Otherwise, if the stack is empty, a final closing } is appended. Then, go to the next iteration.

I know it is a long answer and pseudocode would have probably been better (or the actual code which I cannot show... yes it works!), but I tried to explain the best I could. This solution might not work for all cases. For example, there must be one and only one root element (as in XML). This however worked for me. It was basically a simple preorder traversal... Thanks for all the help and of course if someone has an opinion, a better solution, or some cases that this might not work, I would be very happy to hear!

Converting XML to JSON in Android gives Error

Just replace .atom in the url with .geojson

https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_day.geojson

Output:

{
"type": "FeatureCollection",
"metadata": {
"generated": 1619456055000,
"url":"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/significant_day.geojson",
"title": "USGS Significant Earthquakes, Past Day",
"status": 200,
"api": "1.10.3",
"count": 1
},
"features": [
{
"type": "Feature",
"properties": {
"mag": 6.4,
"place": "200 km WSW of Haveluloto, Tonga",
"time": 1619389680681,
"updated": 1619449698040,
"tz": null,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us6000e4rl",
"detail": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us6000e4rl.geojson",
"felt": 1,
"cdi": 2.7,
"mmi": 3.689,
"alert": "green",
"status": "reviewed",
"tsunami": 0,
"sig": 630,
"net": "us",
"code": "6000e4rl",
"ids": ",us6000e4rl,",
"sources": ",us,",
"types": ",dyfi,losspager,moment-tensor,origin,phase-data,shakemap,",
"nst": null,
"dmin": 6.009,
"rms": 1.12,
"gap": 21,
"magType": "mww",
"type": "earthquake",
"title": "M 6.4 - 200 km WSW of Haveluloto, Tonga"
},
"geometry": {
"type": "Point",
"coordinates": [-177.0771,-21.6472,234.29]
},
"id": "us6000e4rl"
}
]
}


Related Topics



Leave a reply



Submit