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文件的三种方式的主要内容,如果未能解决你的问题,请参考以下文章