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

ops/2024/10/21 14:32:38/

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

xml-的优势">1. xml 的优势

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

xml-的解析方式">2. xml 的解析方式

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

xmlpullparser-的组成部分">3. XMLPullParser 的组成部分

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

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

xml-解析示例">4. XML 解析示例

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>

xml-解析">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:// 处理开始标签,在开始的时候创建英雄Listheros = 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 {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.parse_xml).setOnClickListener(new View.OnClickListener() {@Overridepublic 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,还有另一种数据格式非常实用,我们将在下一节揭晓。


http://www.ppmy.cn/ops/27153.html

相关文章

Gateway路由

Route以微服务名-动态获取服务URI 痛点&#xff1a;路由url写死问题。 是什么 https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/global-filters.html#reactive-loadbalancer-client-filter 修改 9527 yml中的url 测试 如果将8001微服务ym1文件端…

python——Pandas库

Pandas 是一个非常强大的 Python 库&#xff0c;专门用于数据处理和分析。在处理 Excel 文件时&#xff0c;它提供了简单且功能丰富的 API&#xff0c;使得读取、写入、筛选、修改以及分析 Excel 数据变得十分便捷。以下是一些常用的 Pandas API 及其应用场景&#xff0c;以及如…

【Numpy】一文向您详细介绍 np.linspace()

【Numpy】一文向您详细介绍 np.linspace() &#x1f308; 欢迎莅临我的个人主页&#x1f448; 这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的计算机专业人士&#xff0c;热衷于分享技术见…

【Docker学习】docker checkpoint简单了解

docker checkpoint是一个试验性的功能&#xff0c;旨在用于测试和反馈&#xff0c;未来不确定是否会发生变化或是被删除掉&#xff0c;现有的功能我们可以简单了解了解。 docker checkpoint主要用于管理检查点&#xff08;CheckPoint&#xff09;。检查点&#xff08;CheckPoi…

python绘制R控制图(Range Chart)

R控制图&#xff08;Range Chart&#xff09;&#xff0c;也称为范围图或移动极差图&#xff0c;是一种用于分析和控制生产过程中的变异性的统计工具。它通常与Xbar控制图&#xff08;均值图&#xff09;一起使用&#xff0c;可以提供关于生产过程变异性的额外信息。以下是R控制…

python vtk 非结构化网格体渲染

import vtk# 创建一个非结构化网格对象 unstructuredGrid vtk.vtkUnstructuredGrid()# 创建点&#xff08;例如&#xff1a;vtkPoints对象&#xff09;并将其设置到非结构化网格对象上 points vtk.vtkPoints() point0 [0.0, 0.0, 0.0] point1 [1.0, 0.0, 0.0] point2 [1.0…

Linux 信号

目录 信号概述 信号的概念&#xff1a; 进程看待信号的方式&#xff1a; 查看信号&#xff1a; 信号的处理方式&#xff1a; 信号的产生 通过kill指令产生信号&#xff1a; 通过终端按键产生信号&#xff1a; 通过系统调用产生信号&#xff1a; 给任意进程发送任意信号&#xf…

ChatGPT 网络安全秘籍(一)

原文&#xff1a;zh.annas-archive.org/md5/6b2705e0d6d24d8c113752f67b42d7d8 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 在不断发展的网络安全领域中&#xff0c;由 OpenAI 推出的 ChatGPT 所代表的生成式人工智能和大型语言模型&#xff08;LLMs&#xf…