SAX是一种占用内存少且解析速度快的解析器,它采用的是事件驱动,它不需要解析完整个文档,而是按照内容顺序,看文档某个部分是否符合xml语法,如果符合就触发相应的事件。所谓的事件就是些回调方法( callback),这些方法定义在ContentHandler中,下面是其主要方法:
口startDocument:当遇到文档的时候就触发这个事件调用这个方法可以在其中做些预处理工作。
口startElement(Stning namespaceURI,String localName,String qName,Attributes atts):当遇开始标签的时候就会触发这个方法。
口endElement(String uri,String localName,String name):当遇到结束标签时触发这个事件,调用此方法可以做些善后工作。
口characters(char[]ch,int start,int length):当遇到xml内容时触发这个方法。
Student.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>
Student.java
package com.supermario.saxxml; public class Student { long Id; //用于存放id信息 String Name; //用于存放Name信息 String Speciality; //用于存放专业信息 long QQ; //用于存放QQ信息 //带参数构造函数,用于初始化类 public Student(long id, String name, String speciality, long qQ) { super(); Id = id; Name = name; Speciality = speciality; QQ = qQ; } //不带参数构造函数 public Student() { super(); } //取得id public long getId() { return Id; } //取得Name public String getName() { return Name; } //取得QQ public long getQQ() { return QQ; } //取得专业信息 public String getSpeciality() { return Speciality; } //设置id public void setId(long id) { Id = id; } //设置姓名 public void setName(String name) { Name = name; } //设置QQ public void setQQ(long qQ) { QQ = qQ; } //设置专业 public void setSpeciality(String speciality) { Speciality = speciality; } }
studentHandler.java
整个解析过程的关键就是使用StudentHandler来解析xml文本。解析过程会一次调用startDocument(),startElement(),character(),endElement()和endDocument()需要注意的是,preTAG这个变量是用来存储当前节点名称的,在endElement0中要记得把它置为空,否则可能引起一些误判断。
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; } }
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/btn1" android:layout_height="wrap_content" android:layout_width="fill_parent" android:text="SAX解析" /> <ListView android:id="@+id/listView1" android:layout_height="wrap_content" android:layout_width="fill_parent" /> </LinearLayout>
SAXXMLActivity.java
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"))); } catch (Exception e) { // TODO: handle exception } return students; } }
运行结果: