Документ XML обычно используется для обмена данными в Интернете. Данные, представленные в формате XML, могут часто обновляться, и их анализ — обычная задача для сетевых приложений.
Существует три типа синтаксических анализаторов для парсинга XML-данных и чтения их в приложениях Android в Kotlin:
- DOM Parser
- SAX Parser
- XMLPullParser
- DOM Parser
- Пример синтаксического анализа XML с использованием DOM Parser
- Activity_main.xml
- empdetail.xml
- custom_list.xml
- MainActivity.kt
- SAX Parser
- Пример разбора XML с использованием SAX Parser
- Activity_main.xml
- empdetail.xml
- custom_list.xml
- MainActivity.kt
- XMLPullParser
- События XmlPullParser
- Пример разбора XML с использованием XMLPullParser
- Activity_main.xml
- employees.xml
- Employee.kt
- XmlPullParserHandler.kt
- MainActivity.kt
DOM Parser
Анализатор Android DOM (Document Object Model) использует объектно-ориентированный подход для создания и анализа XML-файлов в приложениях для Android. Анализатор DOM загружает XML-файл в память для анализа XML-документа. По этой причине он потребляет больше памяти.
Пример синтаксического анализа XML с использованием DOM Parser
В этом примере мы анализируем XML-данные и отображаем их в ListView.
Activity_main.xml
Добавьте ListView в макет activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="example.javatpoint.com.kotlinxmlparsingusingdomparser.MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</android.support.constraint.ConstraintLayout>
empdetail.xml
Создайте XML-документ empdetail.xml в каталоге ресурсов, чтобы проанализировать данные с помощью синтаксического анализатора DOM.
<?xml version="1.0" encoding="utf-8"?>
<records>
<employee>
<name>Sachin Kumar</name>
<salary>50000</salary>
<designation>Developer</designation>
</employee>
<employee>
<name>Rahul Kumar</name>
<salary>60000</salary>
<designation>Team Leader</designation>
</employee>
<employee>
<name>John Mike</name>
<salary>70000</salary>
<designation>Manager</designation>
</employee>
<employee>
<name>Ajay Kumar</name>
<salary>45000</salary>
<designation>Developer</designation>
</employee>
<employee>
<name>Toni Nayer</name>
<salary>55000</salary>
<designation>Marketing</designation>
</employee>
<employee>
<name>Mr Bony</name>
<salary>42000</salary>
<designation>Sales</designation>
</employee>
<employee>
<name>Raj Kumar</name>
<salary>30000</salary>
<designation>Production</designation>
</employee>
<employee>
<name>Rahul Kumar</name>
<salary>60000</salary>
<designation>Team Leader</designation>
</employee>
<employee>
<name>John Mike</name>
<salary>70000</salary>
<designation>Manager</designation>
</employee>
<employee>
<name>Sachin Kumar</name>
<salary>50000</salary>
<designation>Developer</designation>
</employee>
<employee>
<name>Rahul Kumar</name>
<salary>60000</salary>
<designation>Team Leader</designation>
</employee>
<employee>
<name>John Mike</name>
<salary>70000</salary>
<designation>Manager</designation>
</employee>
</records>
custom_list.xml
Создайте собственный макет для отображения списка данных в ListView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="name"
android:textStyle="bold"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />
<TextView
android:id="@+id/salary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="salary"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:textSize="16sp"/>
<TextView
android:id="@+id/designation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="designation"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
MainActivity.kt
Добавьте следующий код для чтения и анализа XML-данных с помощью синтаксического анализатора DOM. Создайте экземпляр объектов DocumentBuilderFactory, DocumentBuilder и Document.
HashMap используется для чтения данных из XML-документа и добавления их в ArrayList().
package example.javatpoint.com.kotlinxmlparsingusingdomparser
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ListView
import android.widget.SimpleAdapter
import org.w3c.dom.Element
import org.w3c.dom.Node
import org.xml.sax.SAXException
import java.io.IOException
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException
class MainActivity : AppCompatActivity() {
var empDataHashMap = HashMap()
var empList: ArrayList<HashMap> = ArrayList()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
try {
val lv = findViewById(R.id.listView)
val istream = assets.open("empdetail.xml")
val builderFactory = DocumentBuilderFactory.newInstance()
val docBuilder = builderFactory.newDocumentBuilder()
val doc = docBuilder.parse(istream)
//reading the tag "employee" of empdetail file
val nList = doc.getElementsByTagName("employee")
for(i in 0 until nList.getLength()) {
if(nList.item(0).getNodeType().equals(Node.ELEMENT_NODE) ) {
//creating instance of HashMap to put the data of node value
empDataHashMap = HashMap()
val element = nList.item(i) as Element
empDataHashMap.put("name", getNodeValue("name", element))
empDataHashMap.put("salary", getNodeValue("salary", element))
empDataHashMap.put("designation", getNodeValue("designation", element))
//adding the HashMap data to ArrayList
empList.add(empDataHashMap)
}
}
val adapter = SimpleAdapter(this@MainActivity, empList, R.layout.custom_list, arrayOf("name", "salary", "designation"), intArrayOf(R.id.name, R.id.salary, R.id.designation))
lv.setAdapter(adapter)
} catch(e: IOException) {
e.printStackTrace()
} catch(e: ParserConfigurationException) {
e.printStackTrace()
} catch(e: SAXException) {
e.printStackTrace()
}
}
// function to return node value
protected fun getNodeValue(tag: String, element: Element): String {
val nodeList = element.getElementsByTagName(tag)
val node = nodeList.item(0)
if(node != null) {
if(node.hasChildNodes()) {
val child = node.getFirstChild()
while(child != null) {
if(child.getNodeType() === Node.TEXT_NODE) {
return child.getNodeValue()
}
}
}
}
return ""
}
}
Выход:

SAX Parser
В Android широко используется SAX(Simple API for XML) для анализа XML. Синтаксический анализатор SAX проверяет XML-документ посимвольно и преобразует его в серию событий, таких как startElement(), endElement() и character(). Чтобы читать и анализировать данные XML с помощью анализатора SAX, нам нужно создать экземпляр объектов SAXParserFactory, SAXParser и DefaultHandler в приложениях Android с помощью Котлин.
Пример разбора XML с использованием SAX Parser
В этом примере мы будем анализировать данные XML с помощью синтаксического анализатора SAX и отображать их в ListView.
Activity_main.xml
Добавьте ListView в макет activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="example.javatpoint.com.kotlinxmlparsingusingsaxparser.MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</android.support.constraint.ConstraintLayout>
empdetail.xml
Создайте XML-документ empdetail.xml в каталоге ресурсов для анализа данных с помощью синтаксического анализатора SAX.
<?xml version="1.0" encoding="utf-8"?>
<records>
<employee>
<name>Sachin Kumar</name>
<salary>50000</salary>
<designation>Developer</designation>
</employee>
<employee>
<name>Rahul Kumar</name>
<salary>60000</salary>
<designation>Team Leader</designation>
</employee>
<employee>
<name>John Mike</name>
<salary>70000</salary>
<designation>Manager</designation>
</employee>
<employee>
<name>Ajay Kumar</name>
<salary>45000</salary>
<designation>Developer</designation>
</employee>
<employee>
<name>Toni Nayer</name>
<salary>55000</salary>
<designation>Marketing</designation>
</employee>
<employee>
<name>Mr Bony</name>
<salary>42000</salary>
<designation>Sales</designation>
</employee>
<employee>
<name>Raj Kumar</name>
<salary>30000</salary>
<designation>Production</designation>
</employee>
<employee>
<name>Rahul Kumar</name>
<salary>60000</salary>
<designation>Team Leader</designation>
</employee>
<employee>
<name>John Mike</name>
<salary>70000</salary>
<designation>Manager</designation>
</employee>
<employee>
<name>Sachin Kumar</name>
<salary>50000</salary>
<designation>Developer</designation>
</employee>
<employee>
<name>Rahul Kumar</name>
<salary>60000</salary>
<designation>Team Leader</designation>
</employee>
<employee>
<name>John Mike</name>
<salary>70000</salary>
<designation>Manager</designation>
</employee>
</records>
custom_list.xml
Создайте собственный макет для отображения списка данных в ListView.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="name"
android:textStyle="bold"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium" />
<TextView
android:id="@+id/salary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="salary"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:textSize="16sp"/>
<TextView
android:id="@+id/designation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="designation"
android:layout_marginLeft="15dp"
android:layout_marginStart="15dp"
android:layout_marginTop="5dp"
android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
MainActivity.kt
Добавьте следующий код для чтения и анализа XML-данных с помощью синтаксического анализатора SAX. Создайте экземпляр объектов SAXParserFactory, SAXParser и DefaultHandler.
HashMap используется для чтения данных из XML-документа и добавления их в ArrayList().
package example.javatpoint.com.kotlinxmlparsingusingsaxparser
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import org.xml.sax.helpers.DefaultHandler
import javax.xml.parsers.SAXParserFactory
import android.widget.ListView
import android.widget.SimpleAdapter
import org.xml.sax.SAXException
import java.io.IOException
import java.util.ArrayList
import java.util.HashMap
import javax.xml.parsers.ParserConfigurationException
import javax.xml.parsers.SAXParser
class MainActivity : AppCompatActivity() {
internal var empList = ArrayList<HashMap>()
internal var empData = HashMap()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val lv:ListView = findViewById(R.id.listView)
try {
//instancing the SAXParserFactory class
val parserFactory:SAXParserFactory = SAXParserFactory.newInstance()
//instancing the SAXParser class
val saxParser:SAXParser = parserFactory.newSAXParser()
val defaultHandler= object : DefaultHandler() {
var currentValue = ""
var currentElement = false
//overriding the startElement() method of DefaultHandler
override fun startElement(uri: String, localName: String, qName: String, attributes: org.xml.sax.Attributes) {
currentElement = true
currentValue = ""
if(localName == "employee") {
empData = HashMap()
}
}
//overriding the endElement() method of DefaultHandler
override fun endElement(uri: String, localName: String, qName: String) {
currentElement = false
if(localName.equals("name", ignoreCase = true))
empData["name"] = currentValue
else if(localName.equals("salary", ignoreCase = true))
empData["salary"] = currentValue
else if(localName.equals("designation", ignoreCase = true))
empData["designation"] = currentValue
else if(localName.equals("employee", ignoreCase = true))
empList.add(empData)
}
//overriding the characters() method of DefaultHandler
override fun characters(ch: CharArray, start: Int, length: Int) {
if(currentElement) {
currentValue = currentValue + String(ch, start, length)
}
}
}
val istream = assets.open("empdetail.xml")
saxParser.parse(istream, defaultHandler)
//creating Adapter class to access the custom list
val adapter = SimpleAdapter(this@MainActivity, empList, R.layout.custom_list, arrayOf("name", "salary", "designation"), intArrayOf(R.id.name, R.id.salary, R.id.designation))
lv.adapter = adapter
} catch(e: IOException) {
e.printStackTrace()
} catch(e: ParserConfigurationException) {
e.printStackTrace()
} catch(e: SAXException) {
e.printStackTrace()
}
}
}
Вывод:

XMLPullParser
Android рекомендует использовать XMLPullParser для разбора файла XML, а не SAX и DOM, потому что это быстро.
Интерфейс org.xmlpull.v1.XmlPullParser предоставляет функциональные возможности для анализа XML-документа с помощью XMLPullParser.
События XmlPullParser
Метод next() класса XMLPullParser перемещает указатель курсора на следующее событие. Как правило, мы используем четыре константы (работает как событие), определенные в интерфейсе XMLPullParser.
- START_TAG: будет прочитан начальный тег XML.
- TEXT: текстовое содержимое было прочитано, текстовое содержимое можно получить с помощью метода getText().
- END_TAG: будет прочитан конечный тег.
- END_DOCUMENT: больше нет доступных событий.
Пример разбора XML с использованием XMLPullParser
В этом примере мы читаем XML-данные и привязываем их к ListView с помощью XMLPullParser.
Activity_main.xml
Добавьте ListView в макет activity_main.xml.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="example.javatpoint.com.kotlinxmlparsingusingxmlpullparser.MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</android.support.constraint.ConstraintLayout>
employees.xml
Создайте XML-документ employee.xml в каталоге ресурсов для анализа данных с помощью XMLPullParser.
<?xml version="1.0" encoding="UTF-8"?>
<employees>
<employee>
<id>1</id>
<name>Sachin Kumar</name>
<salary>50000</salary>
</employee>
<employee>
<id>2</id>
<name>Rahul Kumar</name>
<salary>60000</salary>
</employee>
<employee>
<id>3</id>
<name>John Mike</name>
<salary>70000</salary>
</employee>
<employee>
<id>4</id>
<name>Ajay Kumar</name>
<salary>45000</salary>
</employee>
<employee>
<id>5</id>
<name>Toni Nayer</name>
<salary>55000</salary>
</employee>
<employee>
<id>6</id>
<name>Mr Bony</name>
<salary>42000</salary>
</employee>
<employee>
<id>7</id>
<name>Raj Kumar</name>
<salary>30000</salary>
</employee>
<employee>
<id>8</id>
<name>Rahul Kumar</name>
<salary>60000</salary>
</employee>
<employee>
<id>9</id>
<name>John Mike</name>
<salary>70000</salary>
</employee>
<employee>
<id>10</id>
<name>Sachin Kumar</name>
<salary>50000</salary>
</employee>
<employee>
<id>11</id>
<name>Rahul Kumar</name>
<salary>60000</salary>
</employee>
<employee>
<id>12</id>
<name>John Mike</name>
<salary>70000</salary>
</employee>
</employees>
Employee.kt
Создайте класс модели данных Employee.kt, соответствующий файлу данных XML.
package example.javatpoint.com.kotlinxmlparsingusingxmlpullparser
class Employee {
var id: Int = 0
var name: String? = null
var salary: Float = 0.toFloat()
override fun toString(): String {
return " Id = $id\n Name = $name\n Salary = $salary"
}
}
XmlPullParserHandler.kt
Напишите код для анализа XML-файла с помощью XMLPullParser. В этом классе мы возвращаем всех сотрудников в списке.
package example.javatpoint.com.kotlinxmlparsingusingxmlpullparser
import org.xmlpull.v1.XmlPullParserException
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserFactory
import java.io.IOException
import java.io.InputStream
class XmlPullParserHandler {
private val employees = ArrayList()
private var employee: Employee? = null
private var text: String? = null
fun parse(inputStream: InputStream): List {
try {
val factory = XmlPullParserFactory.newInstance()
factory.isNamespaceAware = true
val parser = factory.newPullParser()
parser.setInput(inputStream, null)
var eventType = parser.eventType
while(eventType != XmlPullParser.END_DOCUMENT) {
val tagname = parser.name
when(eventType) {
XmlPullParser.START_TAG -> if(tagname.equals("employee", ignoreCase = true)) {
// create a new instance of employee
employee = Employee()
}
XmlPullParser.TEXT -> text = parser.text
XmlPullParser.END_TAG -> if(tagname.equals("employee", ignoreCase = true)) {
// add employee object to list
employee?.let { employees.add(it) }
} else if(tagname.equals("id", ignoreCase = true)) {
employee!!.id = Integer.parseInt(text)
} else if(tagname.equals("name", ignoreCase = true)) {
employee!!.name = text
} else if(tagname.equals("salary", ignoreCase = true)) {
employee!!.salary = java.lang.Float.parseFloat(text)
}
else -> {
}
}
eventType = parser.next()
}
} catch(e: XmlPullParserException) {
e.printStackTrace()
} catch(e: IOException) {
e.printStackTrace()
}
return employees
}
}
MainActivity.kt
В этом классе мы отправляем XML-данные в ArrayAdapter и привязываем их к ListView.
package example.javatpoint.com.kotlinxmlparsingusingxmlpullparser
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
import java.io.IOException
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val listView = findViewById(R.id.listView)
var employees: List? = null
try {
val parser = XmlPullParserHandler()
val istream = assets.open("employees.xml")
employees = parser.parse(istream)
val adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, employees)
listView.adapter = adapter
} catch(e: IOException) {
e.printStackTrace()
}
}
}
Выход:

