SAX解析示例代碼和原理


import java.io.File;

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

/**
 * 第一個SAX讀取xml文件程序
 * @author APPle
 *
 */
public class Demo1 {


    public static void main(String[] args) throws Exception{
        //1.創建SAXParser對象
        SAXParser parser = SAXParserFactory.newInstance().newSAXParser();

        //2.調用parse方法
        /**
         * 參數一: xml文檔
         * 參數二: DefaultHandler的子類
         */
        parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
    }

}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * SAX處理程序(如何解析xml文檔)
 * @author APPle
 *
 */
public class MyDefaultHandler extends DefaultHandler {

    /**
     * 開始文檔時調用
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("MyDefaultHandler.startDocument()");
    }

    /**
     * 開始標簽時調用
     * @param qName: 表示開始標簽的標簽名
     * @param attributes: 表示開始標簽內包含的屬性列表
     */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {
        System.out.println("MyDefaultHandler.startElement()-->"+qName);
    }

    /**
     * 結束標簽時調用
     * @param qName: 結束標簽的標簽名稱
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.println("MyDefaultHandler.endElement()-->"+qName);
    }

    /**
     * 讀到文本內容的時調用
     * @param ch: 表示當前讀完的所有文本內容
     * @param start: 表示當前文本內容的開始位置
     * @param length: 表示當前文本內容的長度
     * char[](                                       張三              20)   100
     *                              98 2
     */
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        //得到當前文本內容
        String content = new String(ch,start,length);
        System.out.println("MyDefaultHandler.characters()-->"+content);
    }

    /**
     * 結束文檔時調用
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("MyDefaultHandler.endDocument()");
    }

}

日志輸出:

MyDefaultHandler.startDocument()
MyDefaultHandler.startElement()-->contactList
MyDefaultHandler.characters()-->
    
MyDefaultHandler.startElement()-->contact
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->name
MyDefaultHandler.characters()-->張三
MyDefaultHandler.endElement()-->name
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->age
MyDefaultHandler.characters()-->20
MyDefaultHandler.endElement()-->age
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->phone
MyDefaultHandler.characters()-->134222223333
MyDefaultHandler.endElement()-->phone
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->email
MyDefaultHandler.characters()-->zhangsan@qq.com
MyDefaultHandler.endElement()-->email
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->qq
MyDefaultHandler.characters()-->432221111
MyDefaultHandler.endElement()-->qq
MyDefaultHandler.characters()-->
    
MyDefaultHandler.endElement()-->contact
MyDefaultHandler.characters()-->
    
MyDefaultHandler.startElement()-->contact
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->name
MyDefaultHandler.characters()-->李四
MyDefaultHandler.endElement()-->name
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->age
MyDefaultHandler.characters()-->20
MyDefaultHandler.endElement()-->age
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->phone
MyDefaultHandler.characters()-->134222225555
MyDefaultHandler.endElement()-->phone
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->email
MyDefaultHandler.characters()-->lisi@qq.com
MyDefaultHandler.endElement()-->email
MyDefaultHandler.characters()-->
        
MyDefaultHandler.startElement()-->qq
MyDefaultHandler.characters()-->432222222
MyDefaultHandler.endElement()-->qq
MyDefaultHandler.characters()-->
    
MyDefaultHandler.endElement()-->contact
MyDefaultHandler.characters()-->

MyDefaultHandler.endElement()-->contactList
MyDefaultHandler.endDocument()

import java.io.File;

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

/**
 * 讀取contact.xml文件,完整輸出文檔內容
 * @author APPle
 *
 */
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);
    }

}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * SAX處理器程序
 * @author APPle
 */
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+">");
    }
}

日志輸出:

<contactList>
    <contact id="001">
        <name>張三</name>
        <age>20</age>
        <phone>134222223333</phone>
        <email>zhangsan@qq.com</email>
        <qq>432221111</qq>
    </contact>
    <contact id="002">
        <name>李四</name>
        <age>20</age>
        <phone>134222225555</phone>
        <email>lisi@qq.com</email>
        <qq>432222222</qq>
    </contact>
</contactList>

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

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

/**
 * 使用sax解析把 xml文檔封裝成對象
 * @author APPle
 *
 */
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);
        }
    }
}
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
 * SAX處理程序
 * @author APPle
 *
 */
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);
        }
    }
}

日志輸出:

Contact [age=20, email=zhangsan@qq.com, id=001, name=張三, phone=134222223333, qq=432221111]
Contact [age=20, email=lisi@qq.com, id=002, name=李四, phone=134222225555, qq=432222222]

Contact,xml

<?xml version="1.0" encoding="utf-8"?>
<contactList>
    <contact id="001">
        <name>張三</name>
        <age>20</age>
        <phone>134222223333</phone>
        <email>zhangsan@qq.com</email>
        <qq>432221111</qq>
    </contact>
    <contact id="002">
        <name>李四</name>
        <age>20</age>
        <phone>134222225555</phone>
        <email>lisi@qq.com</email>
        <qq>432222222</qq>
    </contact>
</contactList>

SAX解析原理: 加載一點,讀取一點,處理一點。對內存要求比較低

DOM解析原理:一次性把xml文檔加載進內存,然后在內存中構建Document樹。 對內存要求比較要。     缺點: 不適合讀取大容量的xml文件,容易導致內存溢出。


 

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());}                    [一個類繼承class 類名(extends DefaultHandler)  在調用是創建傳進去
            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)  : 讀到文本內容時調用

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM