9、SAX解析

简介

DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。对内存要求比较要。
缺点: 不适合读取大容量的xml文件,容易导致内存溢出。

SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。

SAX解析工具
SAX解析工具- Sun公司提供的。内置在jdk中。org.xml.sax.*

核心的API:

   SAXParser类: 用于读取和解析xml文件对象
    parse(File f, DefaultHandler dh)方法: 解析xml文件     
            参数一: File:表示 读取的xml文件。
            参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类

例如:

1.创建SAXParser对象  
SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
2.调用parse方法
parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());

DefaultHandler类的API:

void startDocument()  :  在读到文档开始时调用
void endDocument()  :在读到文档结束时调用
void startElement(String uri, String localName, String qName, Attributes attributes)  :读到开始标签时调用                
void endElement(String uri, String localName, String qName)   :读到结束标签时调用
void characters(char[] ch, int start, int length)  : 读到文本内容时调用

对比:
9、SAX解析_第1张图片

案例:


/** * 读取contact.xml文件,完整输出文档内容 * */
public class Demo2 {

    public static void main(String[] args)throws Exception {
        //1.创建SAXParser
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        //2.读取xml文件
        MyDefaultHandler2 handler = new MyDefaultHandler2();
        parser.parse(new File("./src/contact.xml"), handler);
        String content = handler.getContent();
        System.out.println(content);
    }

}
//调用的类
public class MyDefaultHandler2 extends DefaultHandler {
    //存储xml文档信息
    private StringBuffer sb = new StringBuffer();

    //获取xml信息
    public String getContent(){
        return sb.toString();
    }


    /** * 开始标签 */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        sb.append("<"+qName);
        //判断是否有属性
        if(attributes!=null){
            for(int i=0;i<attributes.getLength();i++){
                //得到属性名称
                String attrName = attributes.getQName(i);
                //得到属性值
                String attrValue = attributes.getValue(i);
                sb.append(" "+attrName+"=\""+attrValue+"\"");
            }
        }
        sb.append(">");
    }

    /** * 文本内容 */
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //得到当前读取的文本
        String content = new String(ch,start,length);
        sb.append(content);
    }

    /** * 结束标签 */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        sb.append("</"+qName+">");
    }
}
/** * 使用sax解析把 xml文档封装成对象 * */
public class Demo3 {

    public static void main(String[] args)throws Exception {
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
        MyDefaultHandler3 handler = new MyDefaultHandler3();
        parser.parse(new File("./src/contact.xml"), handler);
        List<Contact> list = handler.getList();
        for (Contact contact : list) {
            System.out.println(contact);
        }
    }
}

//调用的类
public class MyDefaultHandler3 extends DefaultHandler {
    //存储所有联系人对象
    private List<Contact> list = new ArrayList<Contact>();

    public List<Contact> getList(){
        return list;
    }
    //保存一个联系人信息
    private Contact contact;
    /** * 思路: * 1)创建Contact对象 * 2)把每个contact标签内容存入到Contact对象 * 3)把Contact对象放入List中 */
    //用于临时存储当前读到的标签名
    private String curTag;

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        curTag = qName;
        //读取到contact的开始标签创建Contact对象
        if("contact".equals(qName)){
            contact = new Contact();

            //设置id值
            contact.setId(attributes.getValue("id"));
        }
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //当前文本内容
        String content = new String(ch,start,length);

        if("name".equals(curTag)){
            contact.setName(content);
        }

        if("age".equals(curTag)){
            contact.setAge(content);
        }

        if("phone".equals(curTag)){
            contact.setPhone(content);
        }

        if("email".equals(curTag)){
            contact.setEmail(content);
        }

        if("qq".equals(curTag)){
            contact.setQq(content);
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        //设置空时为了避免空格换行设置到对象的属性中
        curTag = null;
        //读到contact的结束标签放入List中
        if("contact".equals(qName)){
            list.add(contact);
        }
    }
}

你可能感兴趣的:(9、SAX解析)