SAX解析XML(源代码)

来源:互联网 发布:java waite() 编辑:程序博客网 时间:2024/06/12 01:43
 

package book.xml;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

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

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

public class SaxXML {

 public static List readXML(String fileName)throws Exception{
  SAXParserFactory spf=SAXParserFactory.newInstance();//创建SAX解析器工厂对象
  SAXParser saxParser=spf.newSAXParser();//使用解析器工厂创建解析器实例
  
  //创建SAX解析器要使用的事件监听器对象
  StudentSAXHandler handler=new StudentSAXHandler();
  saxParser.parse(new File(fileName),handler);//开始解析文件
  return handler.getResult();//获取结果
 }
 public static void main(String[] args) {
  String filename="student.xml";
  List studentBeans=null;
  try{
   studentBeans=SaxXML.readXML(filename);
  }catch(Exception e){
   System.err.println(e.getMessage());
  }
  if(studentBeans!=null){
   System.out.println("解析student.xml文档得到的学生信息:");
   for(int i=0;i<studentBeans.size();i++){
    System.out.println(studentBeans.get(i).toString());
   }
  }
 }
 /**
  * SAX的事件监听器,当处理特定的XML文件的时候,就需要为
  * 其创建一个继承DefaultHandler的类来处理特定的事件
  * 可以说,这实际上就是SAX处理XML文件的核心
  * @author wuhailin
  *
  */
 static class StudentSAXHandler extends DefaultHandler{
  //保存已经读到过但还没有关闭的标签
  Stack tagsStack=new Stack();
  List studentBeans=new ArrayList();
  StudentBean bean=null;
  /**当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作*/
  public void startDocument()throws SAXException{
   System.out.println("--------Parse begin---------");
  }
  /**当文档结束的时候,调用这个方法,可以在其中做一些善后的工作*/
  public void endDocument()throws SAXException{
   System.out.println("--------Parse end-----------");
  }
  /**
   * 当读到一个开始标签的时候,会触发这个方法
   * @param namespaceURI 就是名域
   * @param localName 标签名
   * @param qName 标签的修饰前缀
   * @param atts 这个标签所包含的属性列表
   * @throws SAXException
   */
  public void startDocument(String namespaceURI,String localName,String qName,Attributes atts)throws SAXException{
   tagsStack.push(qName);
   //如果新的标签是"学生",则表示接下来要读取学生。这里之所以需要bean为空,是因为放置学生标签的子标签也有“学生”
   if(bean==null){
    if(qName.equals("学生")){
     System.out.println("--------Processing a student-------");
     bean=new StudentBean();
     bean.setGender(atts.getValue("性别"));
    }
   }
  }
  /**在遇到结束标签的时候,调用这个方法*/
  public void endElement(String namespaceURI,String localName,String qName)throws SAXException{
   String currenttag=(String)tagsStack.pop();//将最近读取的标签弹出
   //最近读取的标签应该与即将关闭的标签一样
   if(!currenttag.equals(qName)){
    throw new SAXException("XML文档格式不正确,标签不匹配");
   }
   //如果关闭的学生,则表示一个StudentBean已经构造完毕
   if(qName.equals("学生")){
    System.out.println("---------Processing a student end--------");
    studentBeans.add(bean);
    bean=null;
   }
  }
  /**处理XML文件中读到的字符串*/
  public void characters(char[] chs,int start,int length)throws SAXException{
   //从栈中得到节点的信息
   String tag=(String)tagsStack.peek();
   String value=new String(chs,start,length);
   if(tag.equals("姓名")){
    bean.setName(value);
   }else if(tag.equals("年龄")){
    bean.setAge(Integer.parseInt(value));
   }else if(tag.equals("电话")){
    bean.setPhone(value);
   }
  }
  public List getResult(){
   return studentBeans;
  }
 }

}