Android XML文檔解析(二)——DOM解析

------------------------------------------------------------------------------------------------------

       此文章僅作爲學習交流所用

       轉載或引用請務必註明原文地址:

       http://blog.csdn.net/luzhenrong45/article/

       或聯繫作者:[email protected] 

       謝謝!                       

------------------------------------------------------------------------------------------------------

 

一.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是這樣規定的:

  1. 整個文檔是一個文檔節點。
  2. 每一個XML標籤是一個元素節點。
  3. 包含在XML元素中的文本是一個文本節點。
  4. 每一個XML屬性是一個屬性節點。 

    

 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文件的解析。仍然以上前面介紹的Android XML文檔解析(一)——SAX解析中的laolu_xml.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>



(二)先看一下DOM解析XML的實際效果圖,其效果跟SAX解析是一樣的。

(三)工程源碼框架

(1)佈局文件main_xml.xml  listview_xml.xml和適配器類MySimpleAdapter都和上篇文章一樣,這裏就不再給出代碼

(2)DOMParseService.java  (核心代碼)

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;
	}

}
 

 

(3)主Activity,按下DOM按鍵,ListView顯示解析結果.

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;

	@Override
	protected 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
	{

		@Override
		public 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();  
	}
	
}


 


 


 


 

 

 


 

發佈了60 篇原創文章 · 獲贊 173 · 訪問量 30萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章