<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Cyh的博客

    Email:kissyan4916@163.com
    posts - 26, comments - 19, trackbacks - 0, articles - 220

    用SAX處理XML文檔

    Posted on 2009-12-20 14:49 啥都寫點 閱讀(346) 評論(0)  編輯  收藏 所屬分類: J2SE
        用DOM處理XML文檔時,需要讀取整個XML文檔,然后在內存中創建DOM樹,生成DOM樹上的每個Node對象。當XML文檔很大時,需要的內存也就很大,開銷較大。本例介紹另一種輕量級的處理XML文檔的方法:SAX(Simple API for XML),將描述學生信息的XML文檔的內容解析成多個學生對象。

         SAX不同于DOM的文檔驅動,它是事件驅動(基于回調機制)的,即SAX不需要讀入整個文檔,文檔的讀入過程也就是SAX的解析過程。
         java.xml.parsers.SAXParser是SAX解析器,由SAX解析器工廠SAXParserFactory的newSAXParser方法創建,SAXParser的parse方法解析XML文檔。
         必須為SAXParser指定事件偵聽器對象,它必須繼承DefaultHandler,程序員必須按需重寫DefaultHander的一些方法,這是SAX解析XML文檔的核心,常常需要被重寫的方法如下:

               startDocument方法:當SAX解析器讀到文檔開頭的內容時,調用該方法。
               endDocument方法:當SAX解析器讀到文檔結束的內容時,調用該方法。
               startElement方法:當SAX解析器讀到標簽開始的內容時,調用該方法。
               endElement方法:當SAX解析器讀到標簽結束的內容時,調用該方法。
               characters方法:當SAX解析器讀到標簽中的文本內容時,調用該方法。



    /**------------------------------------------SaxXML.java-------------------------------------------------*/
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;

    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;

    /**
     * 使用SAX處理XML文檔。SAX是Simple API for XML的縮寫。
     * 與DOM比較而言,SAX是一種輕量型的方法。我們知道,在處理DOM的時候,我們需要讀入整個的XML文檔,然后在內存中創建DOM樹,生成DOM樹上的每個Node對象。當文檔比較小的時候,這不會造成什么問題,但是一旦文檔大起來,處理DOM就會變得相當費時費力。特別是其對于內存的需求,也將是成倍的增長,以至于在某些應用中使用DOM是一件很不劃算的事(比如在applet中)。這時候,一個較好的替代解決方法就是SAX。
     * SAX在概念上與DOM完全不同。首先,不同于DOM的文檔驅動,它是事件驅動的,也就是說,它并不需要讀入整個文檔,而文檔的讀入過程也就是SAX的解析過程。所謂事件驅動,是指一種基于回調(callback)機制的程序運行方法。
     
    */

    public class SaxXML {

        
    public static List readXML(String fileName) throws Exception {
            
    // 創建SAX解析器工廠對象
            SAXParserFactory spf = SAXParserFactory.newInstance();
            
    // 使用解析器工廠創建解析器實例
            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 
    = "students.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文件的時候,
         * 就需要為其創建一個實現了ContentHandler的類來處理特定的事件,
         * 可以說,這個實際上就是SAX處理XML文件的核心。
         
    */

        
    static class StudentSAXHandler extends DefaultHandler {
            
    // 保存已經讀到過但還沒有關閉的標簽。
            java.util.Stack tagsStatck = new java.util.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--------");
            }

            
            
    /**
             * 當讀到一個開始標簽的時候,會觸發這個方法.
             * namespaceURI就是名域,localName是標簽名,qName是標簽的修飾前綴,
             * atts是這個標簽所包含的屬性列表。通過atts,可以得到所有的屬性名和相應的值.
             * <name="">
             
    */

            
    public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
                    
    throws SAXException {
                tagsStatck.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)tagsStatck.pop();
                
    // 最近讀到的標簽應該與即將關閉的標簽一樣。
                if (!currenttag.equals(qName)){
                    
    throw new SAXException("XML文檔格式不正確,標簽不匹配!");
                }

                
    // 如果關閉的是"學生"標簽,則表示一個StudentBean已經構造完畢了。
                if (qName.equals("學生")){
                    System.out.println(
    "------Processing a student end--------");
                    
    // 將bean實例放入學生列表中,同時置空,等待構造下一個實例
                    studentBeans.add(bean);
                    bean 
    = null;
                }

            }


            
    /** 
             * 處理在XML文件中讀到字符串
             * 
    @see org.xml.sax.ContentHandler#characters(char[], int, int)
             
    */

            
    public void characters(char[] chs, int start, int length) throws SAXException {
                
    //    從棧中得到當前節點的信息
                String tag = (String) tagsStatck.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;
            }

        }

    }






                                                                                                           --    學海無涯
            

    主站蜘蛛池模板: 亚洲依依成人精品| 亚洲精品天堂成人片?V在线播放| 国产精品亚洲专区在线观看| 免费一区二区无码东京热| 亚洲女同成人AⅤ人片在线观看 | a级毛片免费播放| 亚洲日韩精品无码专区网站| 亚洲AV永久无码精品网站在线观看| 亚洲大码熟女在线观看| 在线观看人成网站深夜免费| 亚洲人配人种jizz| 毛片免费观看网址| 国产精品亚洲一区二区三区久久| 国产免费高清69式视频在线观看| 一个人免费视频在线观看www| 免费AA片少妇人AA片直播| 亚洲噜噜噜噜噜影院在线播放| 黄页网站在线免费观看| 亚洲色婷婷综合开心网| 久久久WWW成人免费精品| 亚洲色偷偷偷鲁综合| 午夜老司机永久免费看片| 亚洲沟沟美女亚洲沟沟| 成年大片免费视频| 色婷婷六月亚洲综合香蕉| 亚洲偷自拍拍综合网| 无码人妻精品中文字幕免费| 亚洲国产成人va在线观看网址| 十八禁在线观看视频播放免费| 免费中文熟妇在线影片| 春暖花开亚洲性无区一区二区| 99精品视频在线观看免费播放| 亚洲成人影院在线观看| a级在线免费观看| 亚洲人成电影院在线观看| 国产成人免费片在线观看| a毛片视频免费观看影院| 亚洲一卡2卡4卡5卡6卡在线99 | 久久WWW免费人成一看片| 亚洲av无码专区在线观看亚| 久久亚洲AV永久无码精品|