Android解析XML文件的三种方式
16lz
2021-01-23
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; } }
更多相关文章
- android相关技术文档汇总
- Android API中文文档(111) ―― MailTo
- android 模拟键盘鼠标事件相关
- Android相关文档资源大放送 感兴趣的话可以网盘下载(个人收集) 持
- android 地图 infoWindow的每个控件添加点击事件
- Google Android官方文档进程与线程(Processes and Threads)翻译
- Android之USB Camera摄像头节点后移
- 【转载】Android事件分发机制完全解析,带你从源码的角度彻底理解(