SAX解析XML文件

来源:互联网 发布:高捷资本 知乎 编辑:程序博客网 时间:2024/05/16 18:21

SAX是一个解析速度快并且占用内存少的xml解析器。SAX解析XML文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中,SAX会判断当前读到的字符是否符合XML语法中的某部分,如果符合就会触发事件。所谓事件,其实就是一些回调方法,这些方法(事件)定义在ContentHandler接口中。

 

ContentHandler接口中的常用方法:

 

startDocument()

当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理。

 

endDocument()

当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。

 

startElement(String namespaceURI, String localName, String qName, Attributes atts)

当读到一个开始标签的时候,会触发这个方法。

nameSpaceURI:命名空间;

localName:是不带命名空间前缀的标签名;

qName:是带命名空间前缀的标签名;

atts:所有属性名和相应的值。

注意:SAX中一个重要特点就是流式处理,当遇到一个标签的时候,它并不会记录以前所碰到的标签。

 

endElement(String uri, String localName, String name)

当遇到结束标签的时候,调用这个方法。

 

characters(char[] ch, int start, int length)

用来处理在XML文件中读到的内容,第一个参数用于存放文件的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度,使用new String(ch, start, length)就可以获取内容。

 

ContentHandler中有很多接口,如果直接继承它,需要实现每个接口,所以Android中提供了DefaultHandler类,DefaultHandler实现了ContentHandler.所以可以直接继承DefaultHandler,覆盖其中需要的方法。

 

例:

1. XML文件

<?xml version="1.0" encoding="utf-8"?>
    <Students>
         <Student id="0001">
                <name>aaa</name>
                <age>20</age>
        </Student>
        <Student id="0002">
                <name>bbb</name>
                <age>22</age>
        </Student>
        <Student id="0003">
               <name>ccc</name>
               <age>23</age>
        </Student>
</Students>

 

2. Handler文件

package GH.Test;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class StudentHandler extends DefaultHandler
{
 private List<Student> list = null;
 private Student student = null;
 private String preTag = null;
 
 public List<Student> getList()
 {
  return list;
 }

 @Override
 public void startDocument() throws SAXException
 {
  list = new ArrayList<Student>();
 }

 @Override
 public void startElement(String uri, String localName, String qName,
   Attributes attributes) throws SAXException
 {
  if("Student".equals(localName))
  {
   student = new Student();
   student.setId(attributes.getValue(0));
  }
  preTag = localName;
 }

 @Override
 public void endElement(String uri, String localName, String qName)
   throws SAXException
 {
  if("Student".equals(localName) && list != null)
  {
   list.add(student);
   student = null;
  }
  preTag = null;
 }

 @Override
 public void characters(char[] ch, int start, int length)
   throws SAXException
 {
  if(student == null)
  {
   return ;
  }
  
  String data = new String(ch, start, length);
  if("name".equals(preTag))
  {
   student.setName(data);
  }
  else if("age".equals(preTag))
  {
   student.setAge(Integer.parseInt(data));
  }
 }
}

 

3.服务文件

package GH.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

@SuppressWarnings("unused")
public class StudentService
{
 public static List<Student> readStudentXml(InputStream input)
 {
  try
  {
   SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
   SAXParser saxParser = saxParserFactory.newSAXParser();
   StudentHandler stuHandler = new StudentHandler();
   saxParser.parse(input, stuHandler);
   return stuHandler.getList();
  }
  catch (Exception e)
  {
   e.printStackTrace();
  }
  return null;
 }
}

 

4.单元测试文件

package GH.Test;

import java.io.InputStream;
import java.util.List;

import android.test.AndroidTestCase;
import android.util.Log;

public class UnitTest extends AndroidTestCase
{
 private static final String TAG = "UnitTest";
 public void TestReadXml() throws Exception
 {
  InputStream input = UnitTest.class.getClassLoader().getResourceAsStream("Student.xml");
  List<Student> list = StudentService.readStudentXml(input);
  for(Student student : list)
  {
   Log.i(TAG, student.toString());
  }
 }
}

 

原创粉丝点击