50. 【Android教程】xml 数据解析

xml 是一种标记扩展语言(Extension Mark-up Language),学到这里大家对 xml 语言一定不陌生,但是它在 Android 中的运用其实只是冰山一角。抛开 Android,XML 也被广泛运用于各种数据结构中。在运用 xml 编写 Android 布局的过程中,大家有没有好奇我们写的 LinearLayout 或者 RelativeLayout 等布局是怎么变系统解析成 UI 样式的?这一节我们来揭晓谜底。

1. xml 的优势

XML 是一种标记语言,我们目前接触最多的用法就是用来写布局文件。但其实,xml 被广泛用于网络数据传输中,它是一种非常流行的网络数据格式。比如我们可以使用上一节学到的 HttpURLConnect 去向 Service 发起一个 Http 请求,那么 Service 就可以将数据用 xml 的形式下发,无论是从保存还是从解析的角度,xml 都提供了极大的便利。

2. xml 的解析方式

Android 提供了 3 种类型的解析器:DOM 、SAX 、XMLPullParser 。在这三种类型中,唯 XMLPullParser 以其高效易用两大优点被 Android 官方推荐,在实际开发中绝大多数场景都是使用 XMLPullParser,所以本节主要介绍 XMLPullParser 的使用方法。

3. XMLPullParser 的组成部分

虽然写过很多 xml 布局,但是还是来系统的看一下 xml 的组成部分,一个 xml 文件通常由 4 个部分组成:

  • **prolog :**通常在 xml 文件的第一行,包含一些文件的描述信息,比如版本号、编码格式等
  • **Events:**以各个 Tag 开头和结尾的部分
  • **Text:**介于两个 Tag 之间的内容
  • **Attributes:**用来描述每个 Tag 的属性

4. XML 解析示例

4.1 XML 样本

下面我们来解析一个非常简单的 XML,如下:

复制代码
<?xml version="1.0" encoding="utf-8"?>
<heros>
    <hero id="1">
        <name>
            马超
        </name>
        <description>
            刺客
        </description>
    </hero>

    <hero id="2">
        <name>
            妲己
        </name>
        <description>
            法师
        </description>
    </hero>

    <hero id="3">
        <name>
            鲁班
        </name>
        <description>
            射手
        </description>
    </hero>

</heros>

4.2 XML 解析

以上 xml 是一个英雄列表,包含了 3 个英雄对象,每个英雄对象包含名字和描述,下面开始进行解析。

复制代码
    private ArrayList<Hero> parseXML(XmlPullParser parser) throws XmlPullParserException, IOException {
        ArrayList<Hero> heros = null;
        int eventType = parser.getEventType();
        Hero hero = null;

        // 判断是否结束
        while (eventType != XmlPullParser.END_DOCUMENT) {
            String name;
            switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    // 处理开始标签,在开始的时候创建英雄List
                    heros = new ArrayList();
                    break;
                case XmlPullParser.START_TAG:
                    // 处理tag开始,在这里接收英雄及英雄属性
                    name = parser.getName();
                    if (name.equals("hero")) {
                        hero = new Hero();
                        hero.id = parser.getAttributeValue(null, "id");
                    } else if (hero != null) {
                        if (name.equals("name")) {
                            hero.name = parser.nextText();
                        } else if (name.equals("description")) {
                            hero.description = parser.nextText();
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    // 标签结束,将英雄添加到英雄列表
                    name = parser.getName();
                    if (name.equalsIgnoreCase("hero") && hero != null) {
                        heros.add(hero);
                    }
            }
            // 处理下一个标签
            eventType = parser.next();
        }
        return heros;
    }

在parseXML方法中,首先解析 prelog,在这里创建英雄列表 List,然后一次解析英雄标签及内部属性,最后解析完一个英雄立即存入 List 中。

4.3 MainActivity 主逻辑

现在已经写好了 XML 解析方法,那么 MainActivity 的逻辑就非常简单了,我们只需写一个带有一个 Button 的布局,用于触发 XML 的解析,然后在onCreate()中调用设置监听器,并在监听器中调用解析逻辑即可,最后将解析完的内容输入到 Logcat:

复制代码
package com.emercy.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

public class MainActivity extends Activity {

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

        findViewById(R.id.parse_xml).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                XmlPullParserFactory pullParserFactory = null;

                try {
                    try {
                        pullParserFactory = XmlPullParserFactory.newInstance();
                    } catch (XmlPullParserException e) {
                        e.printStackTrace();
                    }
                    XmlPullParser parser = pullParserFactory.newPullParser();

                    InputStream in_s = getApplicationContext().getAssets().open("heros.xml");
                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
                    parser.setInput(in_s, null);

                    ArrayList<Hero> heros = parseXML(parser);

                    String text = "";

                    for (Hero hero : heros) {

                        text += "id : " + hero.getId() + " name : " + hero.getName() + " description : " + hero.getDescription() + "\n";
                    }
                    Log.d("\nXML Parser", text);
                } catch (XmlPullParserException | IOException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

编译运行,点击"解析 xml",查看 Logcat 的输出:

可以看到 log 的输出和 XML 的定义一模一样,到这里 XML 的内容就被解析到 heros 的 list 中了。

5. 小结

本节介绍了一个以前经常接触的数据格式,在 Andorid 中我们的布局可以很方便的用 XML 来编写,重新回到本节开头的问题,Android 系统是如何将我们写好的 XML 布局转换成 UI 样式的呢?是否也可以通过XmlPullParser来完成?

当然,除了编写 Android 布局之外,XML 也是网络传输中常用的数据格式,我们可以将需要的数据通过 XML 格式存储,然后通过上一节学习的 HttpURLConnection 来进行传输。除了 XML,还有另一种数据格式非常实用,我们将在下一节揭晓。

相关推荐
geovindu6 小时前
sql:Search-Optimized SQL Queries using mysql 9.0
android·数据库·sql·mysql·数据库开发·数据库架构
知之则吱吱7 小时前
Android 开发者验证机制迎来新变化:核心要求、实施时间与开发者应对指南
android·google
墨天梦9 小时前
D09_Retrofit接口与数据转换
android·kotlin·retrofit
电商API_1800790524710 小时前
闲鱼商品列表API接口商品详情API接口请求示例(含一份真实响应数据示例)
android·数据挖掘·网络爬虫·跨境电商·反向海淘
我命由我1234510 小时前
Android 广播 - 组件通信
android·java·开发语言·android studio·android jetpack·android-studio·android runtime
阿俊-全栈开发10 小时前
LikeShop 单商户标准版商品管理二开:分类、SKU 规格与库存联动实现
android·likeshop·likeshop开源商城
用户21816970493013 小时前
Kotlin 语法二
android
妖星13 小时前
android 源码分析surfaceFinger是如何通过设置属性启动bootanim
android
JoyMonitor13 小时前
APK mmap 内存增长定位:pagemap 与 DEX 结构联合定位方法
android