Ready to watch this entire course?
Become a member and get unlimited access to the entire skills library of over 4,900 courses, including more Developer and personalized recommendations.Start Your Free Trial Now
- View Offline
- Exploring local data storage options
- Creating an Android virtual device
- Starting a new project
- Defining preferences with Java and activities
- Creating and reading JSON and XML data files
- Creating a new SQLite database
- Inserting and retrieving data in the database
Skill Level Intermediate
I've previously described how to parse XML files using the XML Pull Parser, a streaming parser that's included with the Android SDK. I'm now going to describe an alternative approach using a parser called JDOM. JDOM is a third-party open-source, free solution that works well in both generic Java applications and in Android apps. You can download the binaries for JDOM, but I've included the JAR file. That is the library that you need to include in your application in the exercise files.
I'll get out of the browser and I'll go to my Exercise Files folder. Under the Assets folder, there's a subfolder called Software, and there's a file there called jdom-2.0.3.jar. You can use this or any later version. I'll copy the JAR file to the clipboard. Then I'll go back to Eclipse. Within Eclipse, I'll go to the libs folder of my new project, XMLJDOMParser. I'll go to that libs folder and I'll paste the file into place.
In addition to adding the JAR file to the libs folder, you can also explicitly add the JAR file to the build path for the application, and that will ensure that the JAR file is exported with the application. I'll right-click on the JAR file. Then I'll go to the Build Path menu choice and choose Add to Build Path. That adds JDOM to the referenced libraries for the application. I'm ready for some code. In the existing version of the application, I'm using the ToursPullParser class, a class I created that parses the file with the XML Pull Parser and streams through the file, listening to events for various tags.
As I've described, the code for this parser is somewhat fragmented. You have to keep track of where you are in the streaming and then write conditional logic to handle each of the elements. The reason to use JDOM is because it will significantly decrease the amount of code that you need to write and the fragmentation of that code. As with the XML Pull Parser, I've created a class that uses JDOM. I'll move Eclipse over to the right and go to my exercise files, and I'll go to my Assets folder and from there, to code.
I'll choose this file: ToursJDOMParser.java. I'll copy it to the clipboard. Then I'll return to Eclipse and I'll make it full screen again. I'll close down the Pull Parser class, and I'll paste my new class into the project's default package. Here's the JDOM parser code. Just as with the Pull Parser, it starts by creating some constants.
With JDOM, in addition to the elements for each minor data element, you'll need to define a tag name for the major data element--that is, for the tour--and I've done that right here. Just as with the pull parser class, I've created a method called parseXML, and then I'm using the context that's passed in that points to the current activity and current application, and I'm opening the tours XML file, using its resource ID. For JDOM, I'm creating an InputStream and then passing that to something called a SAXBuilder.
JDOM includes both a DOMBuilder-- that stands for Document Object Model-- and a SAXBuilder, the simple API for XML. Comparing SAX with DOM is a matter of performance and memory management. With DOM, or Document Object Model, the entire XML document is always stored in memory all at the same time. In contrast, the SAXBuilder uses streaming, in a process that's very similar to the XML Pull Parser. What JDOM gives you though is that it hides that process in the background and makes it feel like you have the entire document in memory at all times.
Just as with the PullParser class, I'm creating a list of tour objects, and then I'm ready to parse. Using JDOM, I create a document object. This is a document object that's specific to JDOM, and it's a part of the org.jdom2 package. I get that document object by calling a method called build, passing in a stream that's pointing to the XML file. Then I get a reference to the rootNode of the document. I'm doing that, calling a method called getRootElement.
That returns an instance of the Element class. Notice when I'm working with the JDOM element class I'm having to explicitly name the entire package. That's because there's an element class that's a part of the Android SDK that otherwise would collide. Then I'm creating a list containing an instance of that element class, and I'm doing that by calling a method called getChildren and passing in the name of the tag that contains each tour. So now, I have a list of tours in memory.
Now, I'm looping through the list. I'm using a for-each-style loop. I'm saying for each node in the list, create a new tour object, then go get the data for each of the data elements: the tour ID, the tour title, description, and so on. The tour ID is being parsed into an integer, the tour price into a double, and all the other values are string, or text, values. Then I'm taking all that data packaged up as a tour object and adding it to the list.
Finally, at the end of try block I'm returning the tours object. Unlike the PullParser class, there isn't any other code. This is it. The nature of DOM programming is that it allows you to put all your code in a single place and say, I want to get this field and I want to get that field. And the mechanics of parsing the XML file are hidden from you. It's a simpler programming model, and it takes a lot less code to do the work. Depending on your device and the nature of your XML file, it might even be faster.
If you're not sure whether this is the right approach for you, based on performance, I encourage you to do your own benchmarking. But this class is now a part of our project. So switching from the XML Pull Parser to the JDOM Parser will be a simple matter of changing which class we're using. I'll go back to my Package Explorer and open up my MainActivity. I'll go to the bottom of the onCreate method and I'll change the parser that I'm using. I'll duplicate this line of code, and then I'll change from ToursPullParser to ToursJDOMParser.
I'll change it both in the variable declaration and in the constructor method call. I'll comment out the version that's creating the PullParser object and everything else is exactly the same. I'll save my changes and I'll run the application in the emulator. When the application opens, I'll see that the data is retrieved, parsed, and displayed, looking exactly the same as it did before. Just as with the pull parser, I'm getting back a list of tour objects, and I'm depending on the toString method of the tour class to determine how the data is displayed in each list item.
So, it's your choice. The XML Pull Parser is a tool that's a part of the Android SDK, whereas JDOM has to be added to your application and will add a little bit to the size of your final app. But the JDOM parsing model is a lot cleaner and results in a lot less code. Either of these parsers will do the job, parsing XML and delivering the data to your users.