Android XML文档解析(二)——DOM解析
------------------------------------------------------------------
此文章仅作为学习交流所用
转载或引用请务必注明原文地址:
http://blog.csdn.net/luzhenrong45/article/
或联系作者:luzhenrong45@gmail.com
谢谢!
------------------------------------------------------------------
一.DOM 介绍
DOM(Document Object Module)基于树和节点的文档对象模型,是用与平台和语言无关的方式表示XML文档的官方W3C标准,可用于直接访问XML文档的各个部分。DOM解析XML文件时,会将XML文件的所有内容以文档树方式存放在内存中,然后允许您使用DOM API遍历XML树、检索所需的数据。用DOM解析模型的优点是编程容易,开发人员只需要调用建树的指令,然后利用navigation APIs访问所需的树节点来完成任务。可以很容易的添加和修改树中的元素。但是,因为DOM需要将XML文件的所有内容以文档树方式存放在内存中,所以内存的消耗比较大,特别对于运行Android的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用SAX来解析XML文件,当然,如果XML文件的内容比较小采用DOM也是可行的。
DOM是这样规定的:
DOM是一些节点的集合,由于文档中可能包含有不同类型的信息,所以定义了几种不同类型的节点.DOM中最常见的节点类型有:
(1)元素:Element
元素是XML的基本构件。元素的子节点可以是其它元素、文本节点或两者都有。元素节点还可以只含有属性这一唯一类型的节点。
(2)属性:Attr
属性节点包含关于元素节点的信息,代表某个元素的属性,虽然Attr继承自Node接口,但因为Attr是包含在Element中的,但并不能将其看做是Element的子对象,因为Attr并不是DOM树的一部分
(3)文本:Text
文本节点文本信息,或干脆是空白的文本。
(4)文档:Document
文档节点是整个文档中所有其它节点的父节点
另外,还有节点列表类NodeList
NodeList代表了一个包含一个或者多个Node的列表,根据操作可以将其简化的看做为数组
int
getLength()
Node
item(int index)
index
个项。
二 DOM解析XML步骤
(一)第一步:创建一个工厂类DocumentBuilderFactory,这一点和SAX类似。工厂类也是单例模式,没有提供共有的构造函数,需要使用静态的newInstance()方法获得。
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
(二)第二步:利用DocumentBuilderFactory工厂类实例创建DocumentBuilder对象
DocumentBuilder builder =factory.newDocumentBuilder();
(三)第三步:解析该文件以创建Document对象
Document document = builder.parse(is);
三.SAX解析实例
(一)下面以一个工程实例来实现SAX对XML文件的解析。仍然以上前面介绍的《<?xml version="1.0" encoding="UTF-8"?><persons> <person id="0"> <name>刘德华</name> <sex>男</sex> <age>21</age> </person> <person id="1"> <name>张漫玉</name> <sex>女</sex> <age>22</age> </person> <person id="2"> <name>张易谋</name> <sex>男</sex> <age>23</age> </person> <person id="3"> <name>周新驰</name> <sex>未知</sex> <age>24</age> </person> <person id="4"> <name>纳兰容若</name> <sex>男</sex> <age>25</age> </person></persons> (三)工程源码框架 (1)布局文件main_xml.xml listview_xml.xml和适配器类MySimpleAdapter都和上篇文章一样,这里就不再给出代码 (2)DOMParseService.java (核心代码) (3)主Activity,按下DOM按键,ListView显示解析结果.
(二)先看一下DOM解析XML的实际效果图,其效果跟SAX解析是一样的。package com.laolu.parser;import java.io.InputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import android.util.Log;public class DOMParserService {public List<Map<String,Object>> getPersons(InputStream is) throws Exception{List<Map<String,Object>> persons=new ArrayList<Map<String,Object>>();DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();DocumentBuilder builder =factory.newDocumentBuilder();Document document = builder.parse(is);Element root =document.getDocumentElement();NodeList personNodes=root.getElementsByTagName("person");for(int i=0;i<personNodes.getLength();i++){Map<String,Object> person =new HashMap<String,Object>();Element personElement =(Element) personNodes.item(i);String id=personElement.getAttribute("id");person.put("id", id);NodeList childNodes =personElement.getChildNodes();for(int j=0; j<childNodes.getLength();j++){if(childNodes.item(j).getNodeType()==Node.ELEMENT_NODE)//判断是否为元素{if("name".equals(childNodes.item(j).getNodeName().trim())){ String name=childNodes.item(j).getFirstChild().getNodeValue();person.put("name", name);}else if("sex".equals(childNodes.item(j).getNodeName().trim())) {String sex=childNodes.item(j).getFirstChild().getNodeValue();person.put("sex", sex);}else if("age".equals(childNodes.item(j).getNodeName().trim())){String age=childNodes.item(j).getFirstChild().getNodeValue();person.put("age", age);} } }persons.add(person);} is.close();return persons;}}
package com.laolu.main;import java.io.InputStream;import java.util.List;import java.util.Map;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import com.example.xml.R;import com.laolu.adapter.MySimpleAdapter;import com.laolu.parser.DOMParserService;import com.laolu.parser.SAXForHandler;import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ListView;import android.widget.SimpleAdapter;import android.widget.TextView;public class XML_ParseActivity extends Activity{private static final String SAX="SAX_Parse";private static final String DOM="DOM_Parse";private static final String PULL="Pull_Parse";ListView listView=null;InputStream inputStream=null;SimpleAdapter adapter=null;List<Map<String,Object>> persons=null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main_xml);listView=(ListView) findViewById(R.id.listview);Button saxButton=(Button) findViewById(R.id.sax_btn);Button domButton=(Button) findViewById(R.id.dom_btn);Button pullButton=(Button) findViewById(R.id.pull_btn);saxButton.setOnClickListener(new MyListener());domButton.setOnClickListener(new MyListener());pullButton.setOnClickListener(new MyListener());//通过类装载器将XML资源加载成java能处理的IO流inputStream = this.getClass().getClassLoader().getResourceAsStream("laolu_xml.xml");}public class MyListener implements OnClickListener{@Overridepublic void onClick(View v){switch (v.getId()){case R.id.sax_btn:break;case R.id.dom_btn:try {updateListViewByDOM();} catch (Exception e) {Log.i(DOM, "DOM Exception!!!"); }break;case R.id.pull_btn: break;}}}public void updateListViewBySAX() throws Exception //SAX方式 {SAXForHandler saxForHandler = new SAXForHandler();SAXParserFactory spf = SAXParserFactory.newInstance();SAXParser saxParser = spf.newSAXParser();saxParser.parse(inputStream, saxForHandler); persons = saxForHandler.getPersons();adapter=new MySimpleAdapter(this, persons, R.layout.listview_xml, new String[]{"id","name","sex","age"}, new int[]{R.id.id,R.id.name,R.id.sex,R.id.age});listView.setAdapter(adapter);inputStream.close();}public void updateListViewByDOM() throws Exception //DOM方式{DOMParserService domParserService=new DOMParserService();persons=domParserService.getPersons(inputStream);adapter= new MySimpleAdapter(this, persons, R.layout.listview_xml, new String[]{"id","name","sex","age"}, new int[]{R.id.id,R.id.name,R.id.sex,R.id.age});listView.setAdapter(adapter);inputStream.close(); }}