Logo Icon Logo
A Crowd-sourced Cookbook on Writing Great Android® Apps
GitHub logo Twitter logo OReilly Book Cover Art

Parsing an XML Document Using the DOM API

Author: Ian Darwin
Published? true -- FormatLanguage: W

Problem:

You have data in XML, and you want to transform it into something useful in your application.

Solution:

Android provides a fairly good clone of the standard DOM API used in the Java Standard Edition. Using the DOM API instead of writing your own parsing code just makes sense.

Discussion:

This is the code that parses the XML document containing the list of Recipes in the Android Cookbook, as discussed in Using a RESTful Web Service. The input file has a single recipes root element, followed by a sequence of recipe elements, each with an id and a title with textual content.

The code creates a DOM DocumentBuilderFactory, which can be tailored, for example, to make Schema-aware parsers. In real code this could be created in a static initializer instead of recreating it each time. The DocumentBuilderFactor is used to create a Document Builder, a.k.a. Parser. The Parser expects to be reading from an InputStream, so we convert the data which we have in String form into an array of bytes and construct a ByteArrayInputStream. Again in real life, you would probably want to combine this code with the Web Service consumer so you could simply get the input stream from the network connection and read the XML directly into the Parser, instead of saving it as a String and then wrapping that in a converter as we do here.

Once the elements are parsed, we convert the Document into an array of Data (the singular of Data is Datum, so the class is called Datum) by calling the DOM API methods such as getDocumentElement(), getChildNodes(), and getNodeValue(). Since the DOM API was not invented by Java people, it doesn't use the standard Collections API but has its own collections like NodeList. In DOM's defense, the same or similar APIs are used in a really wide variety of programming language, so it can be sait to be as much a standard as Java's Collections.

Here's the code:

	/** Convert the list of Recipes in the String result from the
	 * web service into an ArrayList of Datum.
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * @throws SAXException 
	 */
	public static ArrayList<Datum> parse(String input) throws Exception {
		
		final ArrayList<Datum> results = new ArrayList<Datum>(1000);
		final DocumentBuilderFactory dbFactory = 
			DocumentBuilderFactory.newInstance();
		final DocumentBuilder parser = dbFactory.newDocumentBuilder();

		final Document document = 
		parser.parse(new ByteArrayInputStream(input.getBytes()));

		Element root = document.getDocumentElement();
		NodeList recipesList = root.getChildNodes();
		for (int i = 0; i < recipesList.getLength(); i++) {
			Node recipe = recipesList.item(i);
			NodeList fields = recipe.getChildNodes();
			String id = ((Element) fields.item(0)).getNodeValue();
			String title = 
				((Element) fields.item(1)).getNodeValue();
			Datum d = new Datum(Integer.parseInt(id), title);
			results.add(d);
		}		
		return results;
	}

In changing this code from Java SE to Android, the only change we had to make was to use getNodeValue() in the retrieval of id and title instead of Java SE's getTextContent(); So the API really is very close.

See Also:

The Web Service is in Using a RESTful Web Service. There is much more on XML in the Java Cookbook chapter on XML.

No records found.