与DOM比较而言,SAX是一种轻量型的方法。在处理DOM的时候,我们需要读入整个的XML文档,然后在内存中创建DOM树,生成DOM树上的每个Node对象。当文档比较小的时候,这不会造成什么问题,但是一旦文档大起来,处理DOM就会变得相当费时费力。SAX在概念上与DOM完全不同。
首先,不同于DOM的文档驱动,它是事件驱动的,也就是说,它并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。解析开始之前,需要向XMLReader注册一个ContentHandler,也就是相当于一个事件监听器,在ContentHandler中定义了很多方法,比如startDocument(),它定制了当在解析过程中,遇到文档开始时应该处理的事情。当XMLReader读到合适的内容,就会抛出相应的事件,并把这个事件的处理权代理给ContentHandler,调用其相应的方法进行响应。
首先创建一个保存数据类,实现属性的构造方法
public class Book {
private String name=null;
private String author=null;
private String age=null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
private String name=null;
private String author=null;
private String age=null;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
创建一个时间监听器,监听文档解析的事件,对事件进行相应的操作,ContentHandler是一个接口,需用一个类实现接口,复写方法。
public class MySAX extends DefaultHandler {
private List<Book> all=null;
private Book book=null;
private String elementName=null;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(this.elementName!=null){ //已经取得元素
String data=new String(ch,start,length);
if("name".equals(this.elementName)){
this.book.setName(data);
} else if("author".equals(this.elementName)){
this.book.setAuthor(data);
}else if("age".equals(this.elementName)){
this.book.setAge(data);
}
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("book".equals(localName)){
this.all.add(book);
this.book=null; //准备保存下次的数据
}
this.elementName=null; //把名称清空
}
@Override
public void startDocument() throws SAXException {
all=new ArrayList<Book>(); //开始解析文档,设置集合
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("book".equals(localName)){
this.book=new Book(); //遇到book节点,实例化Book对象
}
this.elementName=localName; //保存元素名称
}
public List<Book> getAll() {
return all;
}
}
private List<Book> all=null;
private Book book=null;
private String elementName=null;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(this.elementName!=null){ //已经取得元素
String data=new String(ch,start,length);
if("name".equals(this.elementName)){
this.book.setName(data);
} else if("author".equals(this.elementName)){
this.book.setAuthor(data);
}else if("age".equals(this.elementName)){
this.book.setAge(data);
}
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if("book".equals(localName)){
this.all.add(book);
this.book=null; //准备保存下次的数据
}
this.elementName=null; //把名称清空
}
@Override
public void startDocument() throws SAXException {
all=new ArrayList<Book>(); //开始解析文档,设置集合
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if("book".equals(localName)){
this.book=new Book(); //遇到book节点,实例化Book对象
}
this.elementName=localName; //保存元素名称
}
public List<Book> getAll() {
return all;
}
}
在Activity程序中,将文档xml 通过sax解析器解析后,输出到List集合中,显示在textView中;
SAXParser是JAXP中对XMLReader的一个封装类,而XMLReader是定义在SAX2.0种的一个用来解析文档的接口。你可以同样的调用SAXParser或者XMLReader中的parser()方法来解析文档,效果是完全一样的。不过在SAXParser中的parser()方法接受更多的参数,可以对不同的XML文档数据源进行解析,因而使用起来要比XMLReader要方便一些。
public class MyDemo extends Activity {
private TextView name = null;
private TextView author = null;
private TextView age=null;
private Button but = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.name=(TextView) super.findViewById(R.id.name);
this.author=(TextView) super.findViewById(R.id.author);
this.age=(TextView) super.findViewById(R.id.age);
this.but=(Button) super.findViewById(R.id.but);
this.but.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements OnClickListener{
@Override
public void onClick(View arg0) {
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return;// 不存在不操作
}
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "myinfo" + File.separator + "member.xml");
if (!file.exists()) {
return;
}
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser=null;
MySAX sax=new MySAX(); //创建SAX解析器对象
try {
parser=factory.newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
try {
parser.parse(file, sax);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
List<Book> all=sax.getAll();
System.out.println(all.size());
MyDemo.this.name.setText(all.get(1).getName());
MyDemo.this.author.setText(all.get(1).getAuthor());
MyDemo.this.age.setText(all.get(1).getAge());
}
}
}
private TextView name = null;
private TextView author = null;
private TextView age=null;
private Button but = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.main);
this.name=(TextView) super.findViewById(R.id.name);
this.author=(TextView) super.findViewById(R.id.author);
this.age=(TextView) super.findViewById(R.id.age);
this.but=(Button) super.findViewById(R.id.but);
this.but.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements OnClickListener{
@Override
public void onClick(View arg0) {
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return;// 不存在不操作
}
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "myinfo" + File.separator + "member.xml");
if (!file.exists()) {
return;
}
SAXParserFactory factory=SAXParserFactory.newInstance();
SAXParser parser=null;
MySAX sax=new MySAX(); //创建SAX解析器对象
try {
parser=factory.newSAXParser();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
try {
parser.parse(file, sax);
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
List<Book> all=sax.getAll();
System.out.println(all.size());
MyDemo.this.name.setText(all.get(1).getName());
MyDemo.this.author.setText(all.get(1).getAuthor());
MyDemo.this.age.setText(all.get(1).getAge());
}
}
}