浅谈Android Studio 解析XML的三种方法

一丶概述

文件解析要求,json解析和xml解析,前面文章说过Json转实体类,这里就说说解析XML

内容:

Android Studio 解析XML常见的三种方式:DOM PULL SAX (实现XML转实体类并打印输出)

效果演示:

二丶正文

SAX(Simple API for XML) 使用流式处理的方式,它并不记录所读内容的相关信息。它是一种以事件为驱动的XML API,解析速度快,占用内存少。使用回调函数来实现。 缺点是不能倒退。

DOM(Document Object Model) 是一种用于XML文档的对象模型,可用于直接访问XML文档的各个部分。它是一次性全部将内容加载在内存中,生成一个树状结构,它没有涉及回调和复杂的状态管理。 缺点是加载大文档时效率低下。

Pull内置于Android系统中。也是官方解析布局文件所使用的方式。Pull与SAX有点类似,都提供了类似的事件,如开始元素和结束元素。不同的是,SAX的事件驱动是回调相应方法,需要提供回调的方法,而后在SAX内部自动调用相应的方法。而Pull解析器并没有强制要求提供触发的方法。因为他触发的事件不是一个方法,而是一个数字。它使用方便,效率高。

SAX、DOM、Pull的比较: 

1. 内存占用:SAX、Pull比DOM要好; 
2. 编程方式:SAX采用事件驱动,在相应事件触发的时候,会调用用户编好的方法,也即每解析一类XML,就要编写一个新的适合该类XML的处理类。DOM是W3C的规范,Pull简洁。 
3. 访问与修改:SAX采用流式解析,DOM随机访问。 
4. 访问方式:SAX,Pull解析的方式是同步的,DOM逐字逐句

这里不做详细讲解,看注释,上代码

看项目文件,注意XML放的位置,不会建assets参考https://www.jb51.net/article/144766.htm

XML

<?xml version="1.0" encoding="UTF-8" ?>
<persons>
  <person id="23">
    <name>李雷</name>
    <age>30</age>
  </person>
  <person id="20">
    <name>韩梅梅</name>
    <age>25</age>
  </person>
</persons>

person.Java

public class Person {
  Integer id;
  String name;
  Short age;

  public Integer getId() {
    return id;
  }

  public void setId(Integer id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Short getAge() {
    return age;
  }

  public void setAge(Short age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return "Person{" +
        "id=" + id +
        ", name='" + name + '\'' +
        ", age=" + age +
        '}';
  }
}

XMLtoEntityActivity

public class XMLtoEntityActivity extends AppCompatActivity {
  private TextView tv_show_entity;
  private String string = "";
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.xmlto_entity_activity);
    tv_show_entity = (TextView) findViewById(R.id.tv_show_entity);
  }

  public void startXML(View view){
//    SAXService saxService = new SAXService();
//    DOMService domService = new DOMService();
    PULLService pullService = new PULLService();
    try {
      InputStream inputStream = getAssets().open("Users.xml");
//      List<Person> persons = saxService.getPerson(inputStream);
//      List<Person> persons = domService.getPersons(inputStream);
      List<Person> persons = pullService.getPersons(inputStream);
      for (Person person : persons) {
        Log.e("TAG",person.toString());
        string += person.toString();
      }
    } catch (IOException e) {
      e.printStackTrace();
    } catch (Exception e) {
      e.printStackTrace();
    }
    tv_show_entity.setText(string);
  }
}

DOM方法

/**
 * 采用DOM解析XML内容
 */

public class DOMService {
  public List<Person> getPersons(InputStream inputStream) throws Exception {

    List<Person> persons = new ArrayList<>();

    //获取DOM解析器工厂
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    //获DOM解析器
    DocumentBuilder builder = factory.newDocumentBuilder();
    //将解析树放入内存,通过返回值Document来描述结果
    Document document = builder.parse(inputStream);
    //取得根元素<personos>
    Element root = document.getDocumentElement();
    //取得所有person节点集合
    NodeList personNodes = root.getElementsByTagName("person");
    for (int i = 0; i < personNodes.getLength(); i++) {
      Person person = new Person();
      //取得person节点元素
      Element personElement = (Element) personNodes.item(i);
      //取得属性值并设置ID
      person.setId(Integer.parseInt(personElement.getAttribute("id")));
      //获取person的子节点
      NodeList personChilds = personElement.getChildNodes();
      for (int j = 0; j < personChilds.getLength(); j++) {
        //判断当前节点是否是元素类型的节点
        if (personChilds.item(j).getNodeType() == Node.ELEMENT_NODE) {
          Element childElement = (Element) personChilds.item(j);
          if ("name".equals(childElement.getNodeName())) {
            //获取孙节点的值
            person.setName(childElement.getFirstChild().getNodeValue());
          } else if ("age".equals(childElement.getNodeName())) {
            person.setAge(Short.parseShort(childElement.getFirstChild().getNodeValue()));
          }
        }
      }
      persons.add(person);
    }
    return persons;
  }
}

PULL方法

/**
 * 采用PULL解析XML内容
 */

public class PULLService {
  public List<Person> getPersons(InputStream inputStream) throws Exception {
    List<Person> persons = null;
    Person person = null;
    //得到PULL解析器
    XmlPullParser parser = Xml.newPullParser();
    parser.setInput(inputStream,"UTF-8");
    //产生事件
    int eventType = parser.getEventType();
    //如果不是文档结束事件就循环推进
    while (eventType != XmlPullParser.END_DOCUMENT) {
      switch (eventType) {
        case XmlPullParser.START_DOCUMENT://开始文档事件
          persons = new ArrayList<>();
          break;
        case XmlPullParser.START_TAG://开始元素事件
          //获取解析器当前指向的元素的名称
          String name = parser.getName();
          if ("person".equals(name)) {
            person = new Person();
            person.setId(Integer.parseInt(parser.getAttributeValue(0)));
          }
          if (person != null) {
            if ("name".equals(name)) {
              //获取解析器当前指向元素的下一个文本节点的值
              person.setName(parser.nextText());
            }
            if ("age".equals(name)) {
              person.setAge(Short.parseShort(parser.nextText()));
            }
          }
          break;
        case XmlPullParser.END_TAG://结束元素事件
          //判断是都是person的结束事件
          if ("person".equals(parser.getName())) {
            persons.add(person);
            person = null;
          }
          break;
      }
      //进入下一个元素并触发相应的事件
      eventType = parser.next();
    }
    return persons;
  }
}

SAX方法

/**
 * 采用SAX解析XML内容
 */

public class SAXService {
  public List<Person> getPerson(InputStream inputStream) throws Exception {
    //得到SAX解析工厂
    SAXParserFactory factory = SAXParserFactory.newInstance();
    //得到SAX解析器
    SAXParser parser = factory.newSAXParser();
    PersonParser personParser = new PersonParser();
    parser.parse(inputStream,personParser);
    inputStream.close();
    return personParser.getPersons();
  }
  private final class PersonParser extends DefaultHandler {

    private List<Person> persons = null;
    private String tag = null;//记录当前解析到了那个元素节点名称
    private Person person;

    public List<Person> getPersons(){
      return persons;
    }
    //一开始会执行这个方法,所以在这里面完成初始化
    @Override
    public void startDocument() throws SAXException {
      persons = new ArrayList<>();
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
      //判断元素节点是否等于person
      if ("person".equals(localName)) {
        person = new Person();
        //获取数据,参数为索引下标
        person.setId(Integer.parseInt(attributes.getValue(0)));
      }
      tag = localName;
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
      if ("person".equals(localName)) {
        persons.add(person);
        person = null;
      }
      tag = null;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
      if (tag != null) {
        //获取文本节点的数据
        String data = new String(ch, start, length);
        if ("name".equals(tag)) {
          person.setName(data);
        } else if ("age".equals(tag)) {
          person.setAge(Short.parseShort(data));
        }
      }
    }
  }
}

总结:Android开发主流是传json,而XML解析一般跟网络请求,爬虫数据相关。当然两者也是可以相互转换的,Java只强大在于提供了很多的类和方法。只要你愿意学,方法总是有的

源码下载欢迎Star(updating):https://github.com/JinBoy23520/CoderToDeveloperByTCLer

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android中对xml文件解析的3种方式总结

    前言 xml 是数据传输的一种格式,Android 中的布局文件.设置文件等都采用它来表示.Android 中对 xml 文件的解析也有多种方式,下面介绍常用的 3 种方式: Dom . SAX 和 dom4j.下面话不多说了,来一起看看详细的介绍吧. 先看一个简单的 xml 文件: <?xml version="1.0" encoding="UTF-8" standalone="no"?> <书 出版社="骏马&qu

  • Android利用SAX对XML进行增删改查操作详解

    前言 解析XML的方式有很多种,大家比较熟悉的可能就是DOM解析. DOM(文件对象模型)解析:解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以根据DOM接口来操作这个树结构了. 优点:整个文档读入内存,方便操作:支持修改.删除和重现排列等多种功能. 缺点:将整个文档读入内存中,保留了过多的不需要的节点,浪费内存和空间. 使用场合:一旦读入文档,还需要多次对文档进行操作,并且在硬件资源充足的情况下(内存,CPU). 为了解决DOM解析存在的问题,就出现了SAX解析.其特点为: 优

  • Android编程实现XML解析与保存的三种方法详解

    本文实例讲述了Android编程实现XML解析与保存的三种方法.分享给大家供大家参考,具体如下: 简介 在Android开发中,关于XML解析有三种方式,分别是: 1. SAX 基于事件的解析器,解析速度快,占用内存少.非常适合在Android移动设备中使用. 2. DOM 在内存中以树形结构存放,因此检索和更新效率会更高.但是对于特别大的文档,解析和加载整个文档将会很耗资源 3. PULL 基于事件的解析器,不同于SAX是,PULL是主动请求下一个事件,所以在可控上PULL要比SAX实用.An

  • Android利用Dom对XML进行增删改查操作详解

    1. 概述 平常我们一般是使用JSON与服务器做数据通信,JSON的话,直接用GSON或者其他库去解析很简单.但是,其他有些服务器会返回XML格式的文件,这时候就需要去读取XML文件了. XML的解析有三种方式,在Android中提供了三种解析XML的方式:DOM(Document Objrect Model) , SAX(Simple API XML) ,以及Android推荐的Pull解析方式,他们也各有弊端,而这里来看看使用DOM的方式. 2. Dom解析 DOM解析器在解析XML文档时,

  • Android开发中解析xml文件XmlUtils工具类与用法示例

    本文实例讲述了Android开发中解析xml文件XmlUtils工具类与用法.分享给大家供大家参考,具体如下: 1. xmlUtil工具类 package com.example.xmlpaserutil.util; import java.io.InputStream; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullP

  • android 使用XStream解析xml的实例

    1,要解析的xml文件文件 xml="<apps>\n" + " <app>\n" + " <id>1</id>\n" + " <name>burn</name>\n" + " <version>1.0</version>\n" + " <info>\n" + " <

  • Android编程解析XML文件的方法详解【基于XmlPullParser】

    本文实例讲述了Android编程解析XML文件的方法.分享给大家供大家参考,具体如下: 前言 在学习Android的Framework层源码时,Android大量的使用XmlPullParser来解析xml文件的源码.因此,这里也顺道介绍一下XmlPullParser的使用. XML XML(eXtensible Markup Language)中文名为可扩展标记语言.标记指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等. 用途 XML设计用了传送及携带数据信息,

  • Android pull解析xml的实现方法

    Android pull解析xml的实现方法 资源文件: persons.xml <?xml version="1.0" encoding="utf-8" standalone="yes" ?> <persons> <person id="101"> <name>jame</name> <age>18</age> </person>

  • Android解析XML文件升级APK的方法

    安装APK public class DownLoadApk { public static SharedPreferences sharedPrederences = null; //启动安装界面 public static void DownId(Context context, long downId){ DownloadManager mDownloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOA

  • 浅谈Android Studio 解析XML的三种方法

    一丶概述 文件解析要求,json解析和xml解析,前面文章说过Json转实体类,这里就说说解析XML 内容: Android Studio 解析XML常见的三种方式:DOM PULL SAX (实现XML转实体类并打印输出) 效果演示: 二丶正文 SAX(Simple API for XML) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用回调函数来实现. 缺点是不能倒退. DOM(Document Object Model)

  • 详解Android之解析XML文件三种方式(DOM,PULL,SAX)

    1.xml文件代码 <?xml version="1.0" encoding="UTF-8" ?> <%@ page language="java" contentType="text/xml; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core

  • 浅谈Android中多线程切换的几种方法

    我们知道,多线程是Android开发中必现的场景,很多原生API和开源项目都有多线程的内容,这里简单总结和探讨一下常见的多线程切换方式. 我们先回顾一下Java多线程的几个基础内容,然后再分析总结一些经典代码中对于线程切换的实现方式. 几点基础 多线程切换,大概可以切分为这样几个内容:如何开启多个线程,如何定义每个线程的任务,如何在线程之间互相通信. Thread Thread可以解决开启多个线程的问题. Thread是Java中实现多线程的线程类,每个Thread对象都可以启动一个新的线程,注

  • 浅谈Android Studio导出javadoc文档操作及问题的解决

    1.在Android studio中进行打开一个项目的文件之后,然后进行点击Android stuio中菜单中的"tools"的选项.在弹出了下拉菜单中,进行选中下拉菜单中的"Generate JavaDoc"的选项. 2.在弹出界面中 Output directory是你即将生产的javadoc文件的存储位置,图中1指示的位置:正常点击ok即可: 但是如果有异常情况 比如空指针异常或者文档乱码 java.lang.NullPointerException 或者 j

  • 浅谈Android Studio 3.0 工具新特性的使用 Android Profiler 、Device File Explorer

    前言: 其实 studio3.0的工具大家也已经使用过一段时间了,自己呢,就是从bate版开始使用的,我觉得比较好用的几个地方.就几个,可能还没用到其他的精髓. 但我觉的这个两个功能对我是比较实用的.好那么下面就给大家介绍一下吧. 正文: 话不多说咱们直接上图吧.(个人比较喜欢看图说话) 第一个(Android Profiler)我要介绍的就是这个了.(先看一下效果"震撼一下") (图-1) (图-2) (图-3) (厉害不厉害,牛逼不牛逼)那么我们怎么来操作这个工具呢,来咱们接着看图

  • 浅谈Android studio 生成apk文件时的 key store path 的问题

    使用Android studio生成apk文件时,Key store path 是密钥库文件地址的意思,新手菜鸟会想,我怎么知道他在哪里,其实他的地址是你来决定的. 如下图,你选择一个文件夹后,填写file name,然后点击ok就生成了. 大佬们见怪了~ 补充知识:AndroidStudio每次打开项目不自动打开上一次打开的文件.每次打包都需要重新输入key store path 最近在运行AS时,发现每次打开都要重新的打开目录及打开相关的文件,打包必须重新添加签名文件,我也是醉了. 问题原因

  • 浅谈Android Studio 的四种打包方式

    虽然这个博客的内容很简单,但是作为新手的我还是百度了好久才掌握了Android Studio的打包方式,希望对后来人有所帮助.打包的第一种方式 (1)在Android Studio 中选中app这么module,选择菜单栏""Build--Generate signed APK"" (2)弹出窗口 (3)创建密钥库及密钥,创建后会自动选择刚创建的密钥库和密钥(已拥有密钥库跳过) 点击"Create new..."按钮创建密钥库 Key store

  • 浅谈Android Studio JNI生成so库

    1.新建Android studio工程 2.新建class:AppKey.java.主要为了保存密钥 代码块 package com...adminapp.lib.utils.jni; /** * Created by seven on 16/9/8. */ public class AppKey { static { System.loadLibrary("AppKey"); } public static native String WechatId(); public stat

  • 浅谈Android Studio 4.1 更新内容

    概览 Android Studio 4.1 目前已经发布,该版本共修复了2370 个 bug 以及 275 个 issue,主要包含如下新增功能: 设计 Material Design 组件库的更新 开发 Database Inspector 功能 直接在 Android Studio 中运行模拟器 Dagger 导航支持 使用 TensorFlow Lite 模型 构建与测试 Android 模拟器支持折叠屏 Apply Changes 更新 从 AAR 中导出 C/C++ 中的依赖 Nati

  • 浅谈java中math类中三种取整函数的区别

    math类中三大取整函数 1.ceil 2.floor 3.round 其实三种取整函数挺简单的.只要记住三个函数名翻译过来的汉语便能轻松理解三大函数,下面一一介绍 1.ceil,意思是天花板,java中叫做向上取整,大于等于该数字的最接近的整数 例: math.ceil(13.2)=14 math.ceil(-13.2)=-13 2.floor,意思是地板,java中叫做向下取整,小于等于该数字的最接近的整数 例: math.floor(13.2)=13 math.floor(-13.2)=-

随机推荐