XML—XML解析之SAX

黄舟
發布: 2017-02-24 15:06:59
原創
1450 人瀏覽過

1.SAX解析

  • #在使用DOM解析XML文檔時,需要讀取整個XML文檔,並在記憶體中構建整個DOM樹的Document對象,從而再對XML文件進行操作。此種情況下,如果XML文檔特別大,就會消耗計算機的大量內存,嚴重的情況下可能還會導致內存溢出。

  • SAX解析允許在讀取文件的時候,即對文件進行處理,而不必等到整個文件裝載完才對文件進行操作。

  • 透過繼承DefaultHandler,來發展一個SAX解析器

【注意】SAX主要用於XML文件的解析,不能去修改、刪除、新增元素。

1.1.SAX解析機制

sax是一種推式的機制,你建立一個sax解析器,解析器在發現xml文件中的內容時就告訴你(把事件推給你,有點類似java swing中的事件監聽)。如何處理這些發現的內容,由程式設計師自己決定。

在基於sax的程式中,有五個最常用的sax事件:

#1.startDocument()–>告訴你解析器發現了文件的開始,告訴你解析器開始掃描文件
 2.endDocument()–>告訴你解析器發現了文件結尾
 3.startElement()–>告訴你解析器發現了一個起始標籤,該事件告訴你標籤的名稱、該元素所有的屬性名稱和值
4.characters()–>告訴你解析器發現了一些文本,將得到一個字元數組,該數組的偏移量和一個長度偏移量,有這三個變數你可以得到解析器發現的文本
5.endElement()–>告訴你解析器發現了一個結束標籤,該事件告訴你元素的名稱

1.2.SAX解析實例

依然使用DOM解析中用到的XML例子,如下:

<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>
登入後複製
登入後複製

【步驟】:

1.使用SAXParserFactory建立SAX解析工廠

SAXParserFactory spf = SAXParserFactory.newInstance();
登入後複製
登入後複製

2.透過SAX解析工廠得到解析器物件

SAXParser sp = spf.newSAXParser();
登入後複製
登入後複製

3.將解析物件和事件處理器物件關聯

sp.parse("src/myClass.xml",new MyHandler());
登入後複製
登入後複製

這裡的MyHandler需要自己定義,並且它要繼承DefaultHandler,然後在MyHandler類別中重寫上文提到的5個sax事件方法,當然也可以只重寫自己需要的。
例如現在我寫的MyHandler如下:

class MyHandler extends DefaultHandler{    /**
     * 发现文档开始,该函数只会被调用一次
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("startDocument");
    }    /**
     * 发现文档结束,该函数只会被调用一次
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("endDocument");
    }    /**
     * 发现XML中的一个元素开始,会被反复调用
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("元素名称:"+qName);
    }    /**
     * 发现XML中的一个元素结束,会被反复调用
     */
    @Override
    public void endElement(String uri, String localName, String qName)            
    throws SAXException {

    }    /**
     * 发现XML文件中的文本,会被反复调用
     */
    @Override
    public void characters(char[] ch, int start, int length)            
    throws SAXException {        // 显示文本内容
        String text = new String(ch,start,length);        if(!text.trim().equals("")){
            System.out.println(text);
        }
    }
}
登入後複製

運行結果如下:

XML—XML解析之SAX

可以看到,這是對XML文檔的一種遍歷,而sax所能做的也只是遍歷了。


那麼,如果現在我們有這樣一個需求:只顯示所有學生的姓名和年齡,不顯示學生的介紹,怎麼實現呢?

我們可以在MyHandler類別中定義兩個布林變數isName和isAge,在startElement方法中標識是否是姓名元素或年齡元素,如果是的話才在characters方法中取得對應的文本,如下:

1.定義兩個布林變數

private boolean isName = false;private boolean isAge = false;
登入後複製
登入後複製

2.在startElement方法中加入判斷

@Overridepublic void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {    if(qName.equals("名字")){        this.isName = true;
    }else if(qName.equals("年龄")){        this.isAge = true;
    }
}
登入後複製

#3.在characters方法中根據標識符進行判斷是否取得文字

@Overridepublic void characters(char[] ch, int start, int length)        throws SAXException {    // 显示文本内容
    String text = new String(ch,start,length);    if(!text.trim().equals("")&&(isName||isAge)){
        System.out.println(text);
    }
    isName = false;
    isAge = false;
}
登入後複製
登入後複製

最後要記得將兩個布林變數重設為false。
運行結果如下:

XML—XML解析之SAX

1.SAX解析

  • 在使用DOM解析XML文檔時,需要讀取整個XML文檔,在記憶體中建構整個DOM樹的Document對象,從而再對XML文檔進行操作。此種情況下,如果XML文檔特別大,就會消耗計算機的大量內存,嚴重的情況下可能還會導致內存溢出。

  • SAX解析允許在讀取文件的時候,即對文件進行處理,而不必等到整個文件裝載完才對文件進行操作。

  • 透過繼承DefaultHandler,來發展一個SAX解析器

【注意】SAX主要用於XML文件的解析,不能去修改、刪除、新增元素。

1.1.SAX解析機制

sax是一種推式的機制,你建立一個sax解析器,解析器在發現xml文件中的內容時就告訴你(把事件推給你,有點類似java swing中的事件監聽)。如何處理這些發現的內容,由程式設計師自己決定。

在基於sax的程式中,有五個最常用的sax事件:

1.startDocument()–>告诉你解析器发现了文档的开始,告诉你解析器开始扫描文档
2.endDocument()–>告诉你解析器发现了文档结尾
3.startElement()–>告诉你解析器发现了一个起始标签,该事件告诉你标签的名称、该元素所有的属性名和值
4.characters()–>告诉你解析器发现了一些文本,将得到一个字符数组,该数组的偏移量和一个长度偏移量,有这三个变量你可以得到解析器发现的文本
5.endElement()–>告诉你解析器发现了一个结束标签,该事件告诉你元素的名称

1.2.SAX解析实例

依然使用DOM解析中用到的XML例子,如下:

<?xml version="1.0" encoding="utf-8" standalone="no"?><班级>
    <学生 地址="香港">
        <名字>周小星</名字>
        <年龄>23</年龄>
        <介绍>学习刻苦</介绍>
    </学生>
    <学生 地址="澳门">
        <名字>林晓</名字>
        <年龄>25</年龄>
        <介绍>是一个好学生</介绍>
    </学生></班级>
登入後複製
登入後複製

【步骤】:

1.使用SAXParserFactory创建SAX解析工厂

SAXParserFactory spf = SAXParserFactory.newInstance();
登入後複製
登入後複製

2.通过SAX解析工厂得到解析器对象

SAXParser sp = spf.newSAXParser();
登入後複製
登入後複製

3.将解析对象和事件处理器对象关联

sp.parse("src/myClass.xml",new MyHandler());
登入後複製
登入後複製

这里的MyHandler需要自己定义,并且它要继承DefaultHandler,然后在MyHandler类中重写上文提到的5个sax事件方法,当然也可以只重写自己需要的。
比如现在我写的MyHandler如下:

class MyHandler extends DefaultHandler{    /**
     * 发现文档开始,该函数只会被调用一次
     */
    @Override
    public void startDocument() throws SAXException {
        System.out.println("startDocument");
    }    /**
     * 发现文档结束,该函数只会被调用一次
     */
    @Override
    public void endDocument() throws SAXException {
        System.out.println("endDocument");
    }    /**
     * 发现XML中的一个元素开始,会被反复调用
     */
    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        System.out.println("元素名称:"+qName);
    }    /**
     * 发现XML中的一个元素结束,会被反复调用
     */
    @Override
    public void endElement(String uri, String localName, String qName)            
    throws SAXException {

    }    /**
     * 发现XML文件中的文本,会被反复调用
     */
    @Override
    public void characters(char[] ch, int start, int length)            
    throws SAXException {        // 显示文本内容
        String text = new String(ch,start,length);        
        if(!text.trim().equals("")){
            System.out.println(text);
        }
    }
}
登入後複製

运行结果如下:

XML—XML解析之SAX

可以看到,这是对XML文档的一种遍历,而sax能够做的也只是遍历了。


那么,如果现在我们有这样一个需求:只显示所有学生的姓名和年龄,不显示学生的介绍,怎么实现呢?

我们可以在MyHandler类中定义两个布尔变量isName和isAge,在startElement方法中标识是否是姓名元素或者年龄元素,如果是的话才在characters方法中获取对应的文本,如下:

1.定义两个布尔变量

private boolean isName = false;private boolean isAge = false;
登入後複製
登入後複製

2.在startElement方法中添加判断

@Overridepublic void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {    if(qName.equals("名字")){        
        this.isName = true;
    }else if(qName.equals("年龄")){        this.isAge = true;
    }
}
登入後複製

3.在characters方法中根据标识符进行判断是否获取文本

@Overridepublic void characters(char[] ch, int start, int length)        throws SAXException {    // 显示文本内容
    String text = new String(ch,start,length);    if(!text.trim().equals("")&&(isName||isAge)){
        System.out.println(text);
    }
    isName = false;
    isAge = false;
}
登入後複製
登入後複製

最后要记得将两个布尔变量复位成false。
运行结果如下:

XML—XML解析之SAX

 以上就是XML—XML解析之SAX的内容,更多相关内容请关注PHP中文网(www.php.cn)!


相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板