Android解析XML文件的三种方式

Posted yarsnwoing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android解析XML文件的三种方式相关的知识,希望对你有一定的参考价值。

android解析XML文件的三种方式

DOM解析

整理自《Android经典项目案例开发实战宝典》

DOM解析的时候会将所有的内容读取到内存中。
这种解析方式也会将XML中的换行符解析进来。
待解析的文本:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <fruit id="1" name="apple" ><fruit id="01" name="grap">10yuan</fruit></fruit>
    <fruit id="2" name="banana" >
     3yuan
    </fruit>
    <fruit id="3" name="pear" />
</resources>
package com.supermario.domxml;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class DomXMLActivity extends Activity 
    //新建一个按钮用于响应用户按键
    private Button start;
    //新建一个TextView用于存放结果
    private TextView show;
    //Assets中的xml文件名称
    private String fileName="fruit.xml";
    InputStream inStream=null;
    /** 首次创建界面时运行*/
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        show=(TextView)findViewById(R.id.show);
        start=(Button)findViewById(R.id.start);

        try 
            //从Assets中获取文件
            inStream = this.getAssets().open(fileName);
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        //为按键绑定事件
        start.setOnClickListener(new OnClickListener()
            @Override
            public void onClick(View v) 
                // TODO Auto-generated method stub
                //用于存放结果字符串
                String result="";
                //解析字符流
                result=parse(inStream);
                //将结果显示到界面上
                show.setText(result);
               
        );
    
    //解析字符流
    public String parse(InputStream inStream)
    
        String result="";
        //实例化一个DocumentBuilderFactory类
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        DocumentBuilder builder=null;
        Document doc=null;
        try 
            //实例化一个DocumentBuilder用于解析字符流
            builder=dbf.newDocumentBuilder();
         catch (ParserConfigurationException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        try 
            //解析字符流
            doc=builder.parse(inStream);
         catch (SAXException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
         catch (IOException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
        Element ele=doc.getDocumentElement();
        //获取所有的“fruit”节点
        NodeList nl=ele.getElementsByTagName("fruit");
        if(nl != null && nl.getLength() != 0)
        
            for(int i=0;i<nl.getLength();i++)
            
                Element entry=(Element)nl.item(i);
                //用于获取属性
                result += "name:"+entry.getAttribute("name")+"-->";
                //用于获取文本内容
                result += entry.getTextContent()+"\\n";
            
        
        return result;
    

SAX解析

SAX采用的事件驱动,它不需要解析完整个文档,而是按照内容顺序,如果符合XML语法,就开始解析。
解析的时候会回调定义在ConrtentHandler中的方法,主要方法有:
1 startDocument: 遇到文档开始的时候回调,通常在这里做一些预处理的工作。
2 startElement(String uri, String localName, String qName,
Attributes attributes): 当遇到开始标签的时候调用
3 endElement(): 遇到结束标签的时候调用,可以做一些善后工作。
4 characters(char[] ch,int start,int length): 遇到xml内容的时候触发这个方法。

<?xml version="1.0" encoding="utf-8"?>   
<stundets> 
    <student id="20120812115"> 
      <name>张三</name> 
      <speciality>通信工程</speciality> 
      <qq>843200157</qq> 
    </student>
    <student id="20120812116">
      <name>李四</name> 
      <speciality>网络工程</speciality> 
      <qq>812256156</qq> 
    </student> 
    <student id="20120812117">
      <name>王五</name> 
      <speciality>软件工程</speciality>
      <qq>812750158</qq>
    </student> 
</stundets>
package com.supermario.saxxml;

import java.util.ArrayList;  
import java.util.Iterator;  
import java.util.List;  
import javax.xml.parsers.SAXParserFactory;  
import org.xml.sax.InputSource;  
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class SaxXMLActivity extends Activity   

    //新建一个按键
    private Button button;  
    //新建一个列表
    private ListView listView;
    //新建一个数组列表用于存放字符串数组
    private ArrayList<String> list=new ArrayList<String>();  
public void onCreate(Bundle savedInstanceState)   
    super.onCreate(savedInstanceState);  
    setContentView(R.layout.main); 
    button=(Button)findViewById(R.id.btn1);  
    listView=(ListView) findViewById(R.id.listView1);
    //为按键绑定监听器
    button.setOnClickListener(new ButtonListener());  
  

class ButtonListener implements OnClickListener  

    @Override  
    public void onClick(View v)   
      //将解析后的结果存储到students中   
       List<Student> students=parserXMl();
       //枚举数组中的元素
       for (Iterator iterator = students.iterator(); iterator.hasNext();)   
           Student student = (Student) iterator.next();  
           //将类的内容转换成字符串,依次存储到list中
           list.add(String.valueOf(student.getId())+" "+student.getName()+" "+student.getSpeciality()+" "+String.valueOf((student.getQQ())));  
      
       //新建一个适配器daapter用于给listview提供数据
       ArrayAdapter<String> adapter=new ArrayAdapter<String>(SaxXMLActivity.this, android.R.layout.simple_list_item_1, list);  
      //为listview绑定适配器
       listView.setAdapter(adapter);  
      


  
  //解析xml文件
private List<Student> parserXMl()  
  
    //实例化一个SAX解析工厂
    SAXParserFactory factory=SAXParserFactory.newInstance();  
    List<Student>students=null;   
    try 
    //获取xml解析器
    XMLReader reader=factory.newSAXParser().getXMLReader();  
    students=new ArrayList<Student>();  
    reader.setContentHandler(new StudentHandler(students));  
    //解析Assets下的student.xml文件
    reader.parse(new InputSource(SaxXMLActivity.this.getResources().getAssets().open("student.xml"))); //parse()传入的参数是InputSource的类型
     catch (Exception e)   
    // TODO: handle exception   
    
    return students;  
  
  
package com.supermario.saxxml;

import java.util.List;   
import org.xml.sax.Attributes;  
import org.xml.sax.SAXException;  
import org.xml.sax.helpers.DefaultHandler;  
import android.util.Log;

public class StudentHandler extends DefaultHandler   
    private String preTAG;    //用于存储xml节点的名称
    private List<Student> ListStudent;  
    private Student stu;  
    //无参数实例化类
    public StudentHandler()   
        super();  
    
    //带参数实例化类
    public StudentHandler(List<Student> listStudent)   
        super();  
        ListStudent = listStudent;  
    
    //开始解析文档
    public void startDocument() throws SAXException   
        // TODO Auto-generated method stub   
    Log.i("------>", "文档开始");  
        super.startDocument();  
    
    //开始解析文档的元素
    public void startElement(String uri, String localName, String qName,  
            Attributes attributes) throws SAXException   
        Log.i("localName-------->", localName);  
        preTAG=localName;  //将当前元素的名称保存到preTAG
        if ("student".equals(localName))   
            stu=new Student();  //实例化一个student类
            //将ID信息保存到stu中
            stu.setId(Long.parseLong(attributes.getValue(0)));  

        for (int i = 0; i < attributes.getLength(); i++)     
            Log.i("attributes-------->",String.valueOf(stu.getId()));  
              
          
        //这句话记得要执行
        super.startElement(uri, localName, qName, attributes);  
      

    public void endDocument() throws SAXException   

        Log.i("------>", "文档结束");  
        super.endDocument();  
      
    public void endElement(String uri, String localName, String qName)  
            throws SAXException   
        preTAG="";  
        if ("student".equals(localName))   
        ListStudent.add(stu);  
        Log.i("-------->", "一个元素解析完成");  
          
        super.endElement(uri, localName, qName);  
         
    //解析节点文本内容
    public void characters(char[] ch, int start, int length)  
        throws SAXException   

        String str; 
        //找出元素中的“name”节点
       if ("name".equals(preTAG))   
           str=new String(ch,start,length);  
            stu.setName(str);  
            Log.i("name=", stu.getName());  
        //找出元素中的“speciality”节点
        else if ("speciality".equals(preTAG))   
            str=new String(ch,start,length);  
            stu.setSpeciality(str);  
            Log.i("speciality=", stu.getSpeciality());
        //找出元素中的“qq”节点
        else if ("qq".equals(preTAG))   
            str=new String(ch,start,length);  
            stu.setQQ(Long.parseLong((str)));  
            Log.i("QQ=", String.valueOf(stu.getQQ()));  
         
        super.characters(ch, start, length);  
                    
    public List<Student> getListStudent()   
        return ListStudent;  
    

    public void setListStudent(List<Student> listStudent)   
        ListStudent = listStudent;  
       
  

PULL解析

SAX需要解析完整个文档,当我们只需要解析某个文档中的一部分时,采用PULL解析的方式更加的合适。
PULL解析允许我们主动从解析器获取事件,我们可以在某一时间点,主动的不再获取事件,结束解析。

<?xml version="1.0" encoding="utf-8"?>   
<stundets>
    <student id="20120812115">
      <name>张三</name>
      <speciality>通信工程</speciality> 
      <qq>843200157</qq> 
    </student>
    <student id="20120812116">
      <name>李四</name> 
      <speciality>网络工程</speciality> 
      <qq>812256156</qq> 
    </student> 
    <student id="20120812117">
      <name>王五</name> 
      <speciality>软件工程</speciality>
      <qq>812750158</qq>
    </student> 
</stundets>
package xom.supermario.pullxml;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class PullXMLActivity extends Activity 
    //新建一个按键
    private Button button;  
    //新建一个列表
    private ListView listView;
    //新建一个数组列表用于存放字符串数组
    private ArrayList<String> list=new ArrayList<String>();  
    public void onCreate(Bundle savedInstanceState)   
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main); 
        button=(Button)findViewById(R.id.btn1);  
        listView=(ListView) findViewById(R.id.listView1);
        //为按键绑定监听器
        button.setOnClickListener(new ButtonListener());  
      

    class ButtonListener implements OnClickListener  

        @Override  
        public void onClick(View v)   
          //将解析后的结果存储到students中   
           List<Student> students=parserXMl();
        //  List<Student> students=null;
           //枚举数组中的元素
           for (Iterator iterator = students.iterator(); iterator.hasNext();)   
               Student student = (Student) iterator.next();  
               //将类的内容转换成字符串,依次存储到list中
               list.add(String.valueOf(student.getId())+" "+student.getName()+" "+student.getSpeciality()+" "+String.valueOf((student.getQQ())));  
          
           //新建一个适配器daapter用于给listview提供数据
           ArrayAdapter<String> adapter=new ArrayAdapter<String>(PullXMLActivity.this, android.R.layout.simple_list_item_1, list);  
          //为listview绑定适配器
           listView.setAdapter(adapter);  
          


      

      //解析xml文件
    private List<Student> parserXMl()  
    
        //初始化一个List<student>变量,用于将所有student成员
        List<Student> students=null;
        //初始化一个student变量,用于存储每一个节点的信息
        Student stu=null;
        try
            //打开资源文件student.xml
            InputStream inputstream=PullXMLActivity.this.getResources().getAssets().open("student.xml");
            //创建XmlParser有两种方式
            //方式一:使用工厂类XmlPullParserFactory
            XmlPullParserFactory pullFactory=XmlPullParserFactory.newInstance();
            XmlPullParser xmlPullParser=pullFactory.newPullParser();
            //方式二:使用Android提供的实用工具类android.util.Xml
            //XmlPullParser xmlPullParser=Xml.newPullParser();
            //设置输入字节流为inputstream,并设置编码方式为“UTF-8”
            xmlPullParser.setInput(inputstream, "UTF-8");
            //取得事件类型,用于开始解析时的判断
            int eventType=xmlPullParser.getEventType();
            //循环遍历整个文件直到解析完毕
            while(eventType != XmlPullParser.END_DOCUMENT)
            
                /*打印log显示事件类型
                *START_DOCUMENT:0
                *END_DOCUMENT:1
                *START_TAG:2
                *END_TAG:3
                *TEXT:4
                */
                Log.e("guojs--->event",eventType+"");
                //用于存储节点名称
                String localName=null;
                switch(eventType)
                
                case XmlPullParser.START_DOCUMENT:
                    //碰到文档开头则实例化students变量,并打印log
                    students=new ArrayList<Student>();
                    Log.e("guojs","start document!");
                    break;
                case XmlPullParser.START_TAG:
                
                    localName=xmlPullParser.getName();
                    if ("student".equals(xmlPullParser.getName()))   
                        stu=new Student();  //实例化一个student类
                        //将ID信息保存到stu中
                        stu.setId(Long.parseLong(xmlPullParser.getAttributeValue(0)));  
                        Log.e("guojs",stu.getId()+"");
                    
                    else if(stu != null)
                    
                        //声明一个变量用于存储节点文本
                        String currentData=null;
                        if("name".equals(xmlPullParser.getName()))
                        
                            /*注意这里nextText()的使用:当前事件为START_TAG,
                             * 如果接下去是文本,就会返回当前的文本内容;如果下一个事件是END_TAG
                             * 就会返回空字符串;否则抛出一个异常。
                             */
                            currentData=xmlPullParser.nextText();
                            //存储”name“的信息
                            stu.setName(currentData);
                        
                        else if("speciality".equals(xmlPullParser.getName()))
                        
                            currentData=xmlPullParser.nextText();
                            //存储专业信息
                            stu.setSpeciality(currentData);
                        else if("qq".equals(xmlPullParser.getName()))
                        
                            currentData=xmlPullParser.nextText();
                            //存储QQ信息
                            stu.setQQ(Long.parseLong(currentData));
                        
                    
                
                break;
                case XmlPullParser.END_TAG:
                
                    localName=xmlPullParser.getName();
                    Log.e("guojs--end tag",localName);
                    if("student".equals(localName) && stu != null)
                    
                        //将stu添加进students数组列表中
                        students.add(stu);
                        //设置stu为空
                        stu = null;
                    
                
                break;
                default:
                    break;
                
                //解析下一个事件
                eventType=xmlPullParser.next();//不需要下一个事件的时候,就可以不调用这条语句。
            
        catch(Exception e)
        
            e.printStackTrace();
        
        return students;
      

以上是关于Android解析XML文件的三种方式的主要内容,如果未能解决你的问题,请参考以下文章

Android中的三种XML解析方式

解析Xml文件的三种方式及其特点

三种解析xml的方式

Android应用界面开发

AOP的三种实现方式之一通过xml配置文件实现

AOP的三种实现方式之一通过xml配置文件实现