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:
01.
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
02.
<
scoreboard
lastUpdated
=
"1292447376"
version
=
"1.0"
>
03.
<
highscores
players
=
"8579"
>
04.
<
score
points
=
"587"
player
=
"twig"
when
=
"1292447376"
></
score
>
05.
<
score
points
=
"447"
player
=
"sheik"
when
=
"1292437376"
></
score
>
06.
<
score
points
=
"396"
player
=
"tux"
when
=
"129242000"
></
score
>
07.
<
score
points
=
"276"
player
=
"nunkii"
when
=
"129241000"
></
score
>
08.
<
score
points
=
"187"
player
=
"Anonymous"
when
=
"129240000"
></
score
>
09.
</
highscores
>
10.
<
scores
submitted
=
"50"
>
11.
<
score
points
=
"587"
player
=
"twig"
when
=
"1292447376"
></
score
>
12.
<
score
points
=
"104"
player
=
"twig"
when
=
"1292447370"
></
score
>
13.
<
score
points
=
"103"
player
=
"twig"
when
=
"1292447360"
></
score
>
14.
<
score
points
=
"50"
player
=
"twig"
when
=
"1292447350"
></
score
>
15.
<
score
points
=
"20"
player
=
"twig"
when
=
"1292447340"
></
score
>
16.
</
scores
>
17.
</
scoreboard
>
Once you've got your XML string, parse it using:
1.
ContentHandler parser =
new
ScoreboardXmlParser();
2.
Xml.parse(strXML, parser);
3.
4.
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.
01.
import
java.util.ArrayList;
02.
import
org.xml.sax.Attributes;
03.
import
org.xml.sax.ContentHandler;
04.
import
org.xml.sax.Locator;
05.
import
org.xml.sax.SAXException;
06.
07.
public
class
ScoreboardXmlParser
implements
ContentHandler {
08.
private
long
lastUpdated;
09.
private
int
totalPlayers;
10.
private
int
totalSubmissionsFromPlayer;
11.
private
ArrayList<Score> highScores;
12.
private
ArrayList<Score> playerScores;
13.
private
ArrayList<Score> m_currentList;
14.
public
Scoreboard scoreboard;
15.
16.
@Override
17.
public
void
startDocument()
throws
SAXException {
18.
highScores =
new
ArrayList<Score>();
19.
playerScores =
new
ArrayList<Score>();
20.
lastUpdated =
0
;
21.
totalPlayers =
0
;
22.
totalSubmissionsFromPlayer =
0
;
23.
}
24.
25.
@Override
26.
public
void
endDocument()
throws
SAXException {
27.
scoreboard =
new
Scoreboard();
28.
scoreboard.lastUpdated = lastUpdated;
29.
scoreboard.totalPlayers = totalPlayers;
30.
scoreboard.totalSubmissionsFromPlayer = totalSubmissionsFromPlayer;
31.
scoreboard.highScores =
new
ArrayList<Score>(highScores);
32.
scoreboard.playerScores =
new
ArrayList<Score>(playerScores);
33.
}
34.
35.
@Override
36.
public
void
startElement(String uri, String localName, String name, Attributes atts)
throws
SAXException {
37.
if
(localName.equals(
"scoreboard"
)) {
38.
lastUpdated = Long.parseLong(atts.getValue(
"lastUpdated"
));
39.
}
40.
else
if
(localName.equals(
"highscores"
)) {
41.
totalPlayers = Integer.parseInt(atts.getValue(
"players"
));
42.
m_currentList = highScores;
43.
}
44.
else
if
(localName.equals(
"scores"
)) {
45.
totalSubmissionsFromPlayer = Integer.parseInt(atts.getValue(
"submitted"
));
46.
m_currentList = playerScores;
47.
}
48.
49.
if
(localName.equals(
"score"
)) {
50.
m_currentList.add(
new
Score(atts));
51.
}
52.
}
53.
54.
@Override
55.
public
void
endElement(String uri, String localName, String name)
throws
SAXException {
56.
if
(localName.equals(
"highscores"
) || (localName.equals(
"scores"
))) {
57.
m_currentList =
null
;
58.
}
59.
}
60.
}
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.