Android解析XML文件的三种方式

DOM解析

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

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

<?xml version="1.0" encoding="utf-8"?><resources>    <fruit id="1" name="apple" ><fruit id="01" name="grap">10yuanfruit>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//用于获取属性                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>843200157qq>     student>    <student id="20120812116">      <name>李四name>       <speciality>网络工程speciality>       <qq>812256156qq>     student>     <student id="20120812117">      <name>王五name>       <speciality>软件工程speciality>      <qq>812750158qq>    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 list=new ArrayList();  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 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 adapter=new ArrayAdapter(SaxXMLActivity.this, android.R.layout.simple_list_item_1, list);        //为listview绑定适配器       listView.setAdapter(adapter);      }  }    //解析xml文件private List parserXMl()  {      //实例化一个SAX解析工厂    SAXParserFactory factory=SAXParserFactory.newInstance();      Liststudents=null;       try {    //获取xml解析器    XMLReader reader=factory.newSAXParser().getXMLReader();      students=new ArrayList();      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 ListStudent;      private Student stu;      //无参数实例化类    public StudentHandler() {          super();      }    //带参数实例化类    public StudentHandler(List 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 getListStudent() {          return ListStudent;      }    public void setListStudent(List listStudent) {          ListStudent = listStudent;      }   }  

PULL解析

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

<?xml version="1.0" encoding="utf-8"?>   <stundets>    <student id="20120812115">      <name>张三name>      <speciality>通信工程speciality>       <qq>843200157qq>     student>    <student id="20120812116">      <name>李四name>       <speciality>网络工程speciality>       <qq>812256156qq>     student>     <student id="20120812117">      <name>王五name>       <speciality>软件工程speciality>      <qq>812750158qq>    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 list=new ArrayList();      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 students=parserXMl();        //  List 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 adapter=new ArrayAdapter(PullXMLActivity.this, android.R.layout.simple_list_item_1, list);            //为listview绑定适配器           listView.setAdapter(adapter);          }      }        //解析xml文件    private List parserXMl()      {        //初始化一个List变量,用于将所有student成员        List 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();                    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;    }  }

更多相关文章

  1. android相关技术文档汇总
  2. Android API中文文档(111) ―― MailTo
  3. android 模拟键盘鼠标事件相关
  4. Android相关文档资源大放送 感兴趣的话可以网盘下载(个人收集) 持
  5. android 地图 infoWindow的每个控件添加点击事件
  6. Google Android官方文档进程与线程(Processes and Threads)翻译
  7. Android之USB Camera摄像头节点后移
  8. 【转载】Android事件分发机制完全解析,带你从源码的角度彻底理解(

随机推荐

  1. [Android]ListView中分割线的设置
  2. [ZT] Android(安卓)开发源码分享
  3. [置顶] Android(安卓)Studio Eclipse运行
  4. Android监听返回键
  5. android ICS4.0.3去掉相机全景模式
  6. 资源分享
  7. android 的那些触摸效果
  8. Android选项卡Tab的实现
  9. Android点击左右按钮实现左右滑动页面切
  10. Android调用系统分享