How to parse a xml file with XmlResourceParser in Android

Here's how to parse xml files stored in /res/xml/ dir with XmlResourceParser.

The xml file to parse in this article is an xml file representing data using custom styleable.

You can parse an xml file using XmlResourceParser. and there are 2 ways.

  • Parsing with hardcoded attributes
  • Parsing with custom styleables

We will do it with both.

Declaring styleable attributes

To express data using Custom styleable in xml, you must first define Styleable.

Create the /res/values/attrs.xml file like this.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="codechacha">
        <attr name="title" format="string" />
        <attr name="url" format="string" />
    </declare-styleable>
</resources>

Create a XML file

Then you can create an xml file as follows. (If no styleable attributes defined, Android Studio will throw an error.)

/res/xml/sites.xml

<?xml version="1.0" encoding="utf-8"?>
<codechacha
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <site app:title="@string/site_title_1"
          app:url="https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/"/>
    <site app:title="@string/site_title_2"
          app:url="https://codechacha.com/ko/android-q-scoped-storage/"/>
    <site app:title="@string/site_title_3"
          app:url="https://codechacha.com/ko/how-to-parse-json-in-android/"/>
    <site app:title="site_title_4"
          app:url="https://codechacha.com/ko/how-to-parse-json-in-android/"/>

</codechacha>

And we define Strings for each language.

/res/values/strings.xml

<resources>
    <string name="app_name">XmlResourceParser</string>

    <string name="site_title_1">How to get stroage size</string>
    <string name="site_title_2">Android Q, Scoped Storage</string>
    <string name="site_title_3">How to parse JSON in android</string>
</resources>

/res/values-ko/strings.xml

<resources>
    <string name="site_title_1">스토리지 크기를 얻는 방법</string>
    <string name="site_title_2">안드로이드 Q, 스코프드 스토리지</string>
    <string name="site_title_3">안드로이드에서 Json을 파싱하는 방법</string>
</resources>

Parsing with hardcoded attributes

Now we need to implement the code to parse the xml.

I implemented it like this. I added some comments for more details.

private fun parseXmlDataV1(parser: XmlResourceParser) {
    var eventType = -1
    val namespace = "http://schemas.android.com/apk/res-auto"
    val defaultValue = 0

    while (eventType != XmlResourceParser.END_DOCUMENT) {
        if (eventType == XmlResourceParser.START_TAG) {
            val element = parser.name

            // Check if the first item is "site"
            if (element == "site") {
                // Get the resource id of "title"
                val titleResId = parser.getAttributeResourceValue(
                    namespace, "title", defaultValue)
                var title: String

                // If titleResId returned is defaultValue,
                // it means it's just a string
                if (titleResId == defaultValue) {
                    // Read just a string.
                    title = parser.getAttributeValue(namespace, "title")
                } else {
                    // Get a string with a resource id
                    title = resources.getString(titleResId)
                }
                // Get a string for "url"
                val url  = parser.getAttributeValue(namespace, "url")
                Log.d(TAG, "title : $title, url: $url")
            }
        }
        eventType = parser.next()
    }
}

Get a xml and Parse it. it will work well.

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    var parser = resources.getXml(R.xml.sites)
    try {
        Log.d(TAG, "Parsing with v1")
        parseXmlDataV1(parser)
    } catch (e: Exception) {
        Log.d(TAG, "Failed to parse a xml file")
    }
}

Result

11-26 22:11:48.701  6385  6385 D MainActivity: title : How to get stroage size, url: https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/
11-26 22:11:48.701  6385  6385 D MainActivity: title : Android Q, Scoped Storage, url: https://codechacha.com/ko/android-q-scoped-storage/
11-26 22:11:48.701  6385  6385 D MainActivity: title : How to parse JSON in android, url: https://codechacha.com/ko/how-to-parse-json-in-android/
11-26 22:11:48.701  6385  6385 D MainActivity: title : site_title_4, url: https://codechacha.com/ko/how-to-parse-json-in-android/

Parsing with styleable attributes

We can parse it using styleable attributes.

private fun parseXmlDataV2(parser: XmlResourceParser) {
    var eventType = -1
    while (eventType != XmlResourceParser.END_DOCUMENT) {
        if (eventType == XmlResourceParser.START_TAG) {
            val element = parser.name

            if (element == "site") {
                // Create TypedArray object from our styleable
                // attrs에 정의한 custom styleable을 가져옵니다.
                val ta: TypedArray = resources.obtainAttributes(
                    parser, R.styleable.codechacha)

                // Parse strings using TypedArray.getString()
                var title = ta.getString(R.styleable.codechacha_title)
                val url  = ta.getString(R.styleable.codechacha_url)
                Log.d(TAG, "title : $title, url: $url")
            }
        }
        eventType = parser.next()
    }
}

Get a xml and Parse it. it will work well.

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    var parser = resources.getXml(R.xml.sites)
    try {
        Log.d(TAG, "Parsing with v2")
        parseXmlDataV2(parser)
    } catch (e: Exception) {
        Log.d(TAG, "Failed to parse a xml file")
    }
}

Result

11-26 22:11:48.701  6385  6385 D MainActivity: title : How to get stroage size, url: https://codechacha.com/ko/get-free-and-total-size-of-volumes-in-android/
11-26 22:11:48.701  6385  6385 D MainActivity: title : Android Q, Scoped Storage, url: https://codechacha.com/ko/android-q-scoped-storage/
11-26 22:11:48.701  6385  6385 D MainActivity: title : How to parse JSON in android, url: https://codechacha.com/ko/how-to-parse-json-in-android/
11-26 22:11:48.701  6385  6385 D MainActivity: title : site_title_4, url: https://codechacha.com/ko/how-to-parse-json-in-android/

You can also see this sample app in GitHub: XmlResourceParser

참고

Related Posts

codechachaCopyright ©2019 codechacha