<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 啥都寫點 閱讀(337) 評論(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在线免费观看| 亚洲免费福利在线视频| 亚洲精品在线免费观看视频| 99热免费在线观看| 8090在线观看免费观看| 亚欧人成精品免费观看| 久久免费看黄a级毛片| 大香人蕉免费视频75| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 日韩在线观看免费| 久久国产乱子伦精品免费午夜 | 亚洲精品无码99在线观看| 久久亚洲国产欧洲精品一| 亚洲欧洲日韩综合| 国产区图片区小说区亚洲区| 13小箩利洗澡无码视频网站免费| 男女免费观看在线爽爽爽视频| 四虎影视精品永久免费网站| 国产亚洲美女精品久久久久狼| 亚洲a级在线观看| 人妻巨大乳hd免费看| 精品国产免费人成电影在线观看| 国产小视频免费观看| 亚洲天堂中文字幕| 日韩国产精品亚洲а∨天堂免| 亚洲免费人成在线视频观看| 免费看韩国黄a片在线观看| 久久精品国产精品亚洲下载| 亚洲国产精品成人久久久| 欧洲乱码伦视频免费国产| 美丽的姑娘免费观看在线播放| 四虎影视免费永久在线观看| 亚洲国产人成在线观看69网站| 日韩国产欧美亚洲v片| 99精品视频在线观看免费播放| 又色又污又黄无遮挡的免费视| 亚洲系列中文字幕| 99久久成人国产精品免费| 久久电影网午夜鲁丝片免费| 亚洲av永久无码精品古装片|