In the early days of Android development, it was an exhaustive task to cover all tags in the document and provide a structured hierarchy for the rest of the project business logic. Nowadays, we are presented with various libraries to parse an XML document– does it mean we can do it more efficiently?
Occasionally, you will be challenged to parse XML in your Android project. Most often, this is a case of parsing XML HTTP responses from a remote server or perhaps a static asset file packaged and provided within the application.
Once upon a time in Android
In the early days of Android development, covering all tags in a document and providing a structured hierarchy for the rest of the project business logic used to be an exhaustive task.
A structured document in XML has a beginning and an end tag which by itself is unnecessary and results in more data for the same amount of information. For example, compared to JSON, XML doesn’t support arrays, but it does support many more data types than just text, numbers and booleans. However, these so-called benefits, often lead to a fragile codebase with high maintenance.
Nowadays, you are presented with various libraries to parse an XML document, so let’s see whether anything has improved and can we do this more efficiently today.
To parse or not to parse?
XmlPullParser is available as the go-to solution ever since API 1. It’s an interface based on specification found on xmlpull.org . A minimal implementation example is provided in the documentation, but once you look at it, you realize how its footprint will grow as your XML document grows.
The natural decision would be to look for a higher level of implementation–which brings us to kxml2. Unfortunately, it’s very old and borderline obsolete. Furthermore, your boilerplate would have boilerplate, execution can be linear and very slow, and there aren‘t any integrations with modern Android tooling.
Simple XML Serialization, or just SimpleXML as we all know it, has been the preferred solution for most Android developers for at least half a dozen years now. It’s a high-performance serialization and configuration framework for Java which works on Android and doesn’t demand any additional configuration in order to serialize objects.
However, when it comes to Android, as a dependency, there are issues with latently dependent libraries with a high collision risk.
The Android implementation assumes excluding StAX modules because they are already included in Android. Reminiscing about this implementation recipe seems redundant, but when encountered for the first time, it will cost you several hours to figure out.
SimpleXML has a bare minimum Kotlin support and relatively hideous model mapping, but the worst part about it is its deprecated Retrofit converter.
Looking at JAXB converter only resulted in an encapsulated disappointment. It’s allegedly fast, but we’ll never know because it does not work on Android.
What are your options, really
Honestly, there is only one option. You probably want to parse an XML document and be done with it in the most simple way there is. You don’t want to bloat your codebase by writing a parser from scratch just for this task or project and, of course, you want the best value with the least implementing effort.
SimpleXML is your only viable choice if you don’t mind deprecation and ugly Kotlin code.
How to use SimpleXML, that is the question
Start by properly adding dependencies.
implementation(’com.squareup.retrofit2:converter-simplexml:2.6.1’) {
exclude module: ’stax’
exclude module: ’stax-api’
exclude module: ’xpp3’
}
Create a simple model with correct annotations.
import org.simpleframework.xml.Attribute
import org.simpleframework.xml.Element
import org.simpleframework.xml.Root
@Root
data class RssResource(
@field:Attribute(name = "version", required = false)
@param:Attribute(name = "version", required = false)
val version: String? = null,
@field:Attribute(name = "base", required = false)
@param:Attribute(name = "base", required = false)
val base: String? = null,
@field:Element(name = "channel", required = false)
@param:Element(name = "channel", required = false)
val channel: ChannelResource? = null
)
JSON to the rescue?
It would be great if you can avoid parsing XML entirely when working on an Android or any other mobile project. Like any other tool, protocol, or language, it has its advantages. However, these are neither relevant nor utilized on a mobile platform.
In most cases, XML can be replaced with JSON or similar.
JSON outperforms XML in terms of speed and memory usage, it supports arrays and has a limited number of supported data types and a simple syntax which implies a robust and stable parsing codebase. Because a mobile platform is connected to the Internet most of the time, dealing with network traffic and bandwidth, JSON has less overhead and uses less data than XML to transfer the same set of information.
The takeaway
Personally, I think XML support on Android sucks and there is no elegant way of dealing with it.
When a legitimate use case strikes, you need to decide what is it you need for parsing and how would you go about implementing it, or whether it would be more efficient to propose an alternative solution to parsing XML altogether.
To parse or not to parse–what’s it going to be?