前言

  前面已经介绍了Android平台下两种解析XML的方法,SAX和PULL,这两个均为事件驱动,以流的形式解析XML文档。现在介绍一种新的方式DOM方式解析XML。

  DOM是一种用于XML文档对象模型,可用于直接访问XML文档的各个部位,在DOM中文档被模拟成树状,其中XML语法的每一组成部分都表示一个节点,DOM允许用户遍历文档树,从父节点移动到子节点和兄弟节点。并利用某节点类型特有的属性(元素具有属性,文本节点具有文本数据)。

  对于DOM而言,XML文档中每一个成分都是一个节点。

  DOM是这样规定的:

  1. 整个文档是一个文档节点。
  2. 每一个XML标签是一个元素节点。
  3. 包含在XML元素中的文本是一个文本节点。
  4. 每一个XML属性是一个属性节点。

DOM解析XML

  DOM解析XML也是需要一个工厂类DocumentBuilderFactory,这一点和SAX、PULL类似。工厂类也是单例模式,没有提供共有的构造函数,需要使用静态的newInstance()方法获得,并且需要工厂类来获取DOM解析器实例,使用DocumentBuilderFactory.newDocumentBuilder()获得的DocumentBuilder对象。

  当获得Document之后,就可以使用parse()解析XML文档,parser多个重载,可以适用于不同的输入。

  下面介绍一下在DOM解析XML过程中,会碰上几个对象,Element、NodeList、Node。说也不太好说清楚,画个图解释一下更直观。

  从图上可以看出,Element为一个元素,可以通过这个元素获取到该元素的属性值(Attribute),以及它的子节点的集合NodeList。而NodeList作为一个装载平级节点的集合,可以通过NodeList获得它内装载的所有平级节点,可以通过索引获取。对于Node,表示最终的节点,根据图示说的,其实Jack文本也是一个文本节点(Node),Node可以获取其节点名称、其值、其属性。所以它们三个是可以相互嵌套的,也不存在说谁一定要在谁的外侧或是内层。

示例程序

  既然已经说了那么多了,现在通过一个示例程序展示一下DOM解析XML。这是一个Android应用程序,为了模拟真实的环境,通过网络读取IIS上的一个静态XML文件内容。直接上代码,注释已经写的很清楚了。

  IIS上的静态XML文档内容:

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. - <persons>
  3. - <person id="23">
  4. <name>Jack</name>
  5. <age>21</age>
  6. </person>
  7. - <person id="20">
  8. <name>Dick</name>
  9. <age>23</age>
  10. </person>
  11. </persons>

  DomService,解析网络传输来的XML文档流:

  1. package cn.bgxt.service;
  2.  
  3. import java.io.InputStream;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6.  
  7. import javax.xml.parsers.DocumentBuilder;
  8. import javax.xml.parsers.DocumentBuilderFactory;
  9. import javax.xml.parsers.ParserConfigurationException;
  10.  
  11. import org.w3c.dom.Document;
  12. import org.w3c.dom.Element;
  13. import org.w3c.dom.Node;
  14. import org.w3c.dom.NodeList;
  15.  
  16. import cn.bgxt.domain.Person;
  17.  
  18. public class DomService {
  19.  
  20. public DomService() {
  21. // TODO Auto-generated constructor stub
  22. }
  23.  
  24. public static List<Person> getPersons(InputStream inputStream) throws Exception
  25. {
  26. List<Person> list=new ArrayList<Person>();
  27. //获取工厂对象,以及通过DOM工厂对象获取DOMBuilder对象
  28. DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
  29. DocumentBuilder builder=factory.newDocumentBuilder();
  30. //解析XML输入流,得到Document对象,表示一个XML文档
  31. Document document=builder.parse(inputStream);
  32. //获得文档中的次以及节点,persons
  33. Element element=document.getDocumentElement();
  34. // 获取Element下一级的person节点集合,以NodeList的形式存放。
  35. NodeList personNodes=element.getElementsByTagName("person");
  36. for(int i=0;i<personNodes.getLength();i++)
  37. {
  38. //循环获取索引为i的person节点
  39. Element personElement=(Element) personNodes.item(i);
  40. Person person=new Person();
  41. //通过属性名,获取节点的属性id
  42. person.setId(Integer.parseInt(personElement.getAttribute("id")));
  43. //获取索引i的person节点下的子节点集合
  44. NodeList childNodes=personElement.getChildNodes();
  45. for(int j=0;j<childNodes.getLength();j++)
  46. {
  47. //循环遍历每个person下的子节点,如果判断节点类型是ELEMENT_NODE,就可以依据节点名称给予解析
  48. if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE)
  49. {
  50. if("name".equals(childNodes.item(j).getNodeName()))
  51. {
  52. //因为文本也是一个文本节点,
  53. //所以这里读取到name节点的时候,
  54. //通过getFirstChild()可以直接获得name节点的下的第一个节点,就是name节点后的文本节点
  55. //取其value值,就是文本的内容
  56. person.setName(childNodes.item(j).getFirstChild().getNodeValue());
  57. }
  58. else if("age".equals(childNodes.item(j).getNodeName()))
  59. {
  60. person.setAge(Integer.parseInt(childNodes.item(j).getFirstChild().getNodeValue()));
  61. }
  62. }
  63. }
  64. //把解析的person对象加入的list集合中
  65. list.add(person);
  66. }
  67. return list;
  68. }
  69. }

  从IIS服务器上获取XML的方式,在另外一篇博客:HTTP协议。中已经介绍了,如果不明白可以去看看,这里就不介绍了。

  Activity的布局就是一个按钮,用于点击出发解析事件,因为是Android4.0+的环境,需要无法在主线程中访问网络,需要使用到多线程的技术,并且不要网了给Android应用增加访问网络的权限。

  1. package cn.bgxt.xmlfordom;
  2.  
  3. import java.io.InputStream;
  4. import java.util.List;
  5. import cn.bgxt.domain.Person;
  6. import cn.bgxt.http.HttpUtils;
  7. import cn.bgxt.service.DomService;
  8. import android.os.Bundle;
  9. import android.app.Activity;
  10. import android.util.Log;
  11. import android.view.Menu;
  12. import android.view.View;
  13. import android.widget.Button;
  14.  
  15. public class MainActivity extends Activity {
  16.  
  17. private Button button;
  18.  
  19. @Override
  20. protected void onCreate(Bundle savedInstanceState) {
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.activity_main);
  23.  
  24. button=(Button)findViewById(R.id.btn);
  25. button.setOnClickListener(new View.OnClickListener() {
  26.  
  27. @Override
  28. public void onClick(View v) {
  29. // Android 4.0+不能在主线程中访问网络
  30. Thread thread=new Thread(new Runnable() {
  31. @Override
  32. public void run() {
  33. try {
  34. String path="http://192.168.1.107:1231/persons.xml";
  35. InputStream inputStream=HttpUtils.getXML(path);
  36. List<Person> list=DomService.getPersons(inputStream);
  37. for(Person person:list)
  38. {
  39. //以日志的形式打印对象内容
  40. Log.i("DOM", person.toString());
  41. }
  42. } catch (Exception e) {
  43. // TODO: handle exception
  44. }
  45. }
  46.  
  47. });
  48. thread.start();
  49. }
  50.  
  51. });
  52.  
  53. }
  54.  
  55. }

  如果解析成功,可以在LogCat中查看到日志。

  示例程序源码

总结

  现在已经讲解的常用的Android应用中解析XML的方法,DOM和PULL、SAX不一样,是文档模型形式的,在解析的时候会把整个XML的内容都读取到内存中,这样对于移动设备而言,是很消耗内存的。而PULL以及SAX都是事件驱动,逐行去解析XML的内容,相对而言保证了解析速度又不会很损耗内存。所以Android应用中一般不推荐使用DOM解析XML,还是偏向于使用SAX、PULL。但是DOM也有它的优点,正因为它是把整个文档都读取到内存中了,可以指定需要查找的数据而无需遍历所有的节点,对于内容比较少的XML而言,还是很方便的。所以解析XML的方法有很多,无法绝对的说明谁好谁坏,主要还是看需求设定的环境来取舍的。

  请支持原创,尊重原创,转载请注明出处。谢谢。

Android--解析XML之DOM的更多相关文章

  1. android解析XML总结(SAX、Pull、Dom三种方式) <转载>

    android解析XML总结(SAX.Pull.Dom三种方式) http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.htm ...

  2. Android解析XML

    在Android平台上可以使用Simple API for XML(SAX) . Document Object Model(DOM)和Android附带的pull解析器解析XML文件. 下面是本例子 ...

  3. 解析XML:DOM,SAX,PULL

    Android解析XML有三种方式:DOM(document object model).SAX(simple api XML).PULL 1.DOM DOM解析XML文件时,会将XML文件的所有内容 ...

  4. android解析xml文件的方式

    android解析xml文件的方式   作者:东子哥 ,发布于2012-11-26,来源:博客园   在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xm ...

  5. JAVA解析XML之DOM方式

    JAVA解析XML之DOM方式 准备工作 创建DocumentBuilderFactory对象;    创建DocumentBuilder对象; 通过DocumentBuilder对象的parse方法 ...

  6. Android解析xml文件-采用DOM,PULL,SAX三种方法解析

    解析如下xml文件 <?xml version="1.0" encoding="UTF-8"?> <persons> <perso ...

  7. android解析xml文件方法之一-----DOM

    Hello.xml文件 <dict num="219" id="219" name="219"> <key>hell ...

  8. [android]解析XML文件的方法有三种:PULL,DOM,SAM

    PULL 的工作原理: XML pull提供了开始元素和结束元素.当某个元素开始时,可以调用parser.nextText从XML文档中提取所有字符数据.当解析到一个文档结束时,自动生成EndDocu ...

  9. android 解析XML方式(二)

    上一节中,我们使用DOM方式解析xml文档,该方式比较符合我们日常思维方式,容易上手,但是它直接把文档调入内存中,比较耗内存.在这里我们可以用另外一种方式解析xml,这个就是SAX方式. SAX即是: ...

  10. android 解析XML方式(一)

    在androd手机中处理xml数据时很常见的事情,通常在不同平台传输数据的时候,我们就可能使用xml,xml是与平台无关的特性,被广泛运用于数据通信中,那么在android中如何解析xml文件数据呢? ...

随机推荐

  1. jsp中的四个作用域,九个内置对象分别是什么?

    九大内置对象: 内置对象(又叫隐含对象),就是在jsp中,不需要创建(由服务器<容器>来创建),可以直接使用的对象. 对象 含义 类 作用域 request 请求对象 类型 javax.s ...

  2. 【Python】【BugList12】python自带IDLE执行print(req.text)报错:UnicodeEncodeError: 'UCS-2' codec can't encode characters in position 93204-93204

    [代码] # -*- coding:UTF-8 -*- import requests if __name__ == '__main__': target = 'https://unsplash.co ...

  3. python的语法小结

    break 与continue的区别: 1.break是直接中断全部循环 2.continue则是在只不执行此次所循环的东西,其它循环依旧执行,比方说只是跳过第4次循环,第5次循环照常进行. \n 表 ...

  4. 企业微信自建应用移动端动态获取li并给其事件问题总结

    前段时间一个项目增加企业微信移动端应用,其中几个小功能用到ul-li列表点击并获得相应数据: 开始用var lis=$('#ul li'); for(var=i;i<lis.length;i++ ...

  5. Python——我所学习的turtle函数库

    1基础概念 1.1 画布(canvas) 画布就是turtle为我们展开用于绘图区域, 我们可以设置它的大小和初始位置. 常用的画布方法有两个:screensize()和setup(). (1)tur ...

  6. 十分钟带你读懂《增长黑客》zz

    背景 “If you are not growing, then you are dying. ”(如果企业不在增长,那么就是在衰亡!) 这句话适用于企业,也适用于个人.人生毕竟不像企业,是非成败,似 ...

  7. python生成exe文件

    安装pyinstaller pyinstaller支持python2和python3 命令行安装:pip install pyinstaller pyinstaller --icon=duoguan. ...

  8. sshd_config 配置文件参数详解

    sshd_config配置详解 名称sshd_config - OpenSSH SSH 服务器守护进程配置文件 大纲/etc/ssh/sshd_config 描述sshd(8) 默认从 /etc/ss ...

  9. webstorm验证码

    2017-2-16 亲测可用 http://idea.imsxm.com/ webstorm10 注册码 User or company Name: EMBRACE ===== LICENSE KEY ...

  10. linux使用framebuffer的代码

    #include <linux/fb.h> #include <sys/mman.h> #include <sys/ioctl.h> #include <st ...