Android: How to parse an XML string

There are quite a few examples on how to parse XML from a resource or InputStream, however only a handful will show you how to parse a String in XML format.

Luckily, the method is very similar to most of the other examples as you still need to use a SAX ContentHandler.

Consider the example XML file:

<?xml version="1.0" encoding="UTF-8"?>
<scoreboard lastUpdated="1292447376" version="1.0">
<highscores players="8579">
<score points="587" player="twig" when="1292447376"></score>
<score points="447" player="sheik" when="1292437376"></score>
<score points="396" player="tux" when="129242000"></score>
<score points="276" player="nunkii" when="129241000"></score>
<score points="187" player="Anonymous" when="129240000"></score>
</highscores>
<scores submitted="50">
<score points="587" player="twig" when="1292447376"></score>
<score points="104" player="twig" when="1292447370"></score>
<score points="103" player="twig" when="1292447360"></score>
<score points="50" player="twig" when="1292447350"></score>
<score points="20" player="twig" when="1292447340"></score>
</scores>
</scoreboard>

Once you've got your XML string, parse it using:

ContentHandler parser = new ScoreboardXmlParser();
Xml.parse(strXML, parser);

Scoreboard sb = parser.scoreboard;

Now for the ContentHandler class. The main functions to implement are:

  • startDocument(): You can use this to initialise any lists to store data.
  • endDocument(): To know when you've finished parsing and clean up after yourself.
  • startElement(): When the parser reaches a new element. You can also access the element attributes here.
  • endElement(): When the element is done with the current element and ready to move onto the next.

Everything else you can leave empty.

This is the complete class.

import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

public class ScoreboardXmlParser implements ContentHandler {
private long lastUpdated;
private int totalPlayers;
private int totalSubmissionsFromPlayer;
private ArrayList<Score> highScores;
private ArrayList<Score> playerScores;
private ArrayList<Score> m_currentList;
public Scoreboard scoreboard;

@Override
public void startDocument() throws SAXException {
highScores = new ArrayList<Score>();
playerScores = new ArrayList<Score>();
lastUpdated = 0;
totalPlayers = 0;
totalSubmissionsFromPlayer = 0;
}

@Override
public void endDocument() throws SAXException {
scoreboard = new Scoreboard();
scoreboard.lastUpdated = lastUpdated;
scoreboard.totalPlayers = totalPlayers;
scoreboard.totalSubmissionsFromPlayer = totalSubmissionsFromPlayer;
scoreboard.highScores = new ArrayList<Score>(highScores);
scoreboard.playerScores = new ArrayList<Score>(playerScores);
}

@Override
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
if (localName.equals("scoreboard")) {
lastUpdated = Long.parseLong(atts.getValue("lastUpdated"));
}
else if (localName.equals("highscores")) {
totalPlayers = Integer.parseInt(atts.getValue("players"));
m_currentList = highScores;
}
else if (localName.equals("scores")) {
totalSubmissionsFromPlayer = Integer.parseInt(atts.getValue("submitted"));
m_currentList = playerScores;
}

if (localName.equals("score")) {
m_currentList.add(new Score(atts));
}
}

@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if (localName.equals("highscores") || (localName.equals("scores"))) {
m_currentList = null;
}
}
}

A little trick here is that both "highscores" and "scores" lists contain an element called "score". I used "m_currentList" to keep track of which list the scores should be added to. Once the parser is finished with either "highscores" or "scores", the list is set back to null.

When the document ends, I just store all the information into into a Scoreboard object. You don't have to do this, but it was just an example to show you what you can do at the end of the parsing.

You should also implement a custom function such as isParsed() to check if the data was parsed correctly or not.

Sources:

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog