Работа с XML

Ресурсы XML и их парсинг

Последнее обновление: 18.10.2021

Одним из распространенных форматов хранения и передачи данных является xml. Рассмотрим, как с ним работать в приложении на Android.

Приложение может получать данные в формате xml различными способами - из ресурсов, из сети и т.д. В данном случае рассмотрим ситуацию, когда файл xml хранится в ресурсах.

Возьмем стандартный проект Android по умолчанию и в папке res создадим каталог xml. Для этого нажмем на каталог res правой кнопкой мыши и в контекстном меню выберем New -> Android Resource Directory:

Добавление папки xml в Android Studio

В появившемся окне в качестве типа ресурсов укажем xml:

Добавление папки ресурсов xml в Android Studio

В этот каталог добавим новый файл, который назовем users.xml и который будет иметь следующее содержимое:

<?xml version="1.0" encoding="utf-8"?>
<users>
    <user>
        <name>Tom</name>
        <age>36</age>
    </user>
    <user>
        <name>Alice</name>
        <age>32</age>
    </user>
    <user>
        <name>Bob</name>
        <age>28</age>
    </user>
</users>

Это обычный файл xml, который хранит набор элементов user. Каждый элемент характеризуется наличием двух подэлементов - name и age. Условно говоря, каждый элемент описывает пользователя, у которого есть имя и возраст.

В папку, где находится основной класс MainActivity, добавим новый класс, который назовем User:

package com.example.xmlapp;

public class User {
    private String name;
    private String age;

    public String getName(){
        return name;
    }
    public String getAge(){
        return age;
    }
    public void setName(String name){
        this.name = name;
    }
    public void setAge(String age){
        this.age = age;
    }
    public String toString(){
        return  "User: " + name + " - " + age;
    }
}

Этот класс описывает товар, информация о котором будет извлекаться из xml-файла.

И в ту же папку добавим новый класс UserResourceParser:

XML-ресурсы в Android Studio и их парсинг с помощью Java

Определим для класса UserResourceParser следующий код:

package com.example.xmlapp;

import org.xmlpull.v1.XmlPullParser;
import java.util.ArrayList;


public class UserResourceParser {
    private ArrayList<User> users;

    public UserResourceParser(){
        users = new ArrayList<>();
    }

    public ArrayList<User> getUsers(){
        return  users;
    }

    public boolean parse(XmlPullParser xpp){
        boolean status = true;
        User currentUser = null;
        boolean inEntry = false;
        String textValue = "";

        try{
            int eventType = xpp.getEventType();
            while(eventType != XmlPullParser.END_DOCUMENT){

                String tagName = xpp.getName();
                switch (eventType){
                    case XmlPullParser.START_TAG:
                        if("user".equalsIgnoreCase(tagName)){
                            inEntry = true;
                            currentUser = new User();
                        }
                        break;
                    case XmlPullParser.TEXT:
                        textValue = xpp.getText();
                        break;
                    case XmlPullParser.END_TAG:
                        if(inEntry){
                            if("user".equalsIgnoreCase(tagName)){
                                users.add(currentUser);
                                inEntry = false;
                            } else if("name".equalsIgnoreCase(tagName)){
                                currentUser.setName(textValue);
                            } else if("age".equalsIgnoreCase(tagName)){
                                currentUser.setAge(textValue);
                            }
                        }
                        break;
                    default:
                }
                eventType = xpp.next();
            }
        }
        catch (Exception e){
            status = false;
            e.printStackTrace();
        }
        return  status;
    }
}

Данный класс выполняет функции парсинга xml. Распарсенные данные будут храниться в переменной users. Непосредственно сам парсинг осуществляется с помощью функции parse. Основную работу выполняет передаваемый в качестве параметра объект XmlPullParser. Этот класс позволяет пробежаться по всему документу xml и получить его содержимое.

Когда данный объект проходит по документу xml, при обнаружении определенного тега он генерирует некоторое событие. Есть четыре события, которые описываются следующими константами:

  • START_TAG: открывающий тег элемента

  • TEXT: прочитан текст элемента

  • END_TAG: закрывающий тег элемента

  • END_DOCUMENT: конец документа

С помощью метода getEventType() можно получить первое событие и потом последовательно считывать документ, пока не дойдем до его конца. Когда будет достигнут конец документа, то событие будет представлять константу END_DOCUMENT:

int eventType = xpp.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT){
	//......................
	eventType = xpp.next();
}

Для перехода к следующему событию применяется метод next().

При чтении документа с помощью метода getName() можно получить название считываемого элемента.

String tagName = xpp.getName();

И в зависимости от названия тега и события мы можем выполнить определенные действия. Например, если это открывающий тег элемента user, то создаем новый объект User и устанавливаем, что мы находимся внутри элемента user:

case XmlPullParser.START_TAG:
	if("user".equalsIgnoreCase(tagName)){
		inEntry = true;
		currentUser = new User();
	}
break;

Если событие TEXT, то считано содержимое элемента, которое мы можем прочитать с помощью метода getText():

case XmlPullParser.TEXT:
	textValue = xpp.getText();
	break;

Если закрывающий тег, то все зависит от того, какой элемент прочитан. Если прочитан элемент user, то добавляем объект User в коллекцию ArrayList и сбрываем переменную inEntry, указывая, что мы вышли из элемента user:

case XmlPullParser.END_TAG:
	if(inEntry){
		if("user".equalsIgnoreCase(tagName)){
			users.add(currentUser);
			inEntry = false;

Если прочитаны элементы name и age, то передаем их значения переменным name и age объекта User:

else if("name".equalsIgnoreCase(tagName)){
	currentUser.setName(textValue);
} else if("age".equalsIgnoreCase(tagName)){
	currentUser.setAge(textValue);
}

Теперь изменим класс MainActivity, который будет загружать ресурс xml:

package com.example.xmlapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

import org.xmlpull.v1.XmlPullParser;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        XmlPullParser xpp = getResources().getXml(R.xml.users);
        UserResourceParser parser = new UserResourceParser();
        if(parser.parse(xpp))
        {
            for(User prod: parser.getUsers()){
                Log.d("XML", prod.toString());
            }
        }
    }
}

Вначале получаем ресурс xml с помощью метода getXml(), в который передается название ресурса. Данный метод возвращает объект XmlPullParser, который затем используется для парсинга. Для простоты просто выводим данные в окне Logcat:

XmlPullParser и парсинг xml-файла в Android и Java
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850