小菜毛毛技術分享

          與大家共同成長

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            164 Posts :: 141 Stories :: 94 Comments :: 0 Trackbacks

          一、        前言

          用 Java解析XML文檔,最常用的有兩種方法:使用基于事件的XML簡單API(Simple API for XML)稱為SAX和基于樹和節點的文檔對象模型(Document Object Module)稱為DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口來使用SAX和DOM,通過JAXP,我們可以使用任何與JAXP兼容的XML解析器。

          JAXP接口包含了三個包:

          (1)       org.w3c.dom  W3C推薦的用于XML標準規劃文檔對象模型的接口。

          (2)       org.xml.sax   用于對XML進行語法分析的事件驅動的XML簡單API(SAX)

          (3)       javax.xml.parsers解析器工廠工具,程序員獲得并配置特殊的特殊語法分析器。

          二、        前提

          DOM編程不要其它的依賴包,因為JDK里自帶的JDK里含有的上面提到的org.w3c.dom、org.xml.sax 和javax.xml.parsers包就可以滿意條件了。

          三、        使用SAX解析XML文檔

          SAX是基于事件的簡單API,同樣的我們也是用一個最簡單的例子來看看SAX是如何解析XML的

          先來看看我們要解析的XML代碼吧

          <?xml version="1.0" encoding="gb2312"?>

          <books>

            <book email="zhoujunhui">

                       <name addr="address">rjzjh</name>

                       <price>jjjjjj</price>

            </book>

          </books>

          簡單的不能再簡單了。但是該有的都有了,根元素、屬性、子節點。好了,能反應問題就行了,下面來看看解析這個XML文件的Java代碼吧!

          1 public class SaxParse {

          2     public SaxParse(){

          3            SAXParserFactory saxfac=SAXParserFactory.newInstance();

          4            try {

          5                   SAXParser saxparser=saxfac.newSAXParser();

          6                   InputStream is=new FileInputStream("bin/library.xml");

          7                   saxparser.parse(is,new MySAXHandler());

          8            } catch (ParserConfigurationException e) {

          9                   e.printStackTrace();

          10           } catch (SAXException e) {

          11                  e.printStackTrace();

          12           } catch (FileNotFoundException e) {

          13                  e.printStackTrace();

          14           } catch (IOException e) {

          15                  e.printStackTrace();

          16           }

          17    }

          18    public static void main(String[] args) {

          19           new SaxParse();

          20    }

          21  }

          這段代碼比較短,因為SAX是事件驅動的,它的大部分實現在在另一個Java文件中,先別管另一個文件,我們來一個個地分析吧!

          (1)得到SAX解析器的工廠實例

          3            SAXParserFactory saxfac=SAXParserFactory.newInstance();

          這是一個javax.xml.parsers.SAXParserFactory類的實例

          (2)從SAX工廠實例中獲得SAX解析器

          5            SAXParser saxparser=saxfac.newSAXParser();

          使用javax.xml.parsers.SAXParserFactory工廠的newSAXParser()方法

          (3)把要解析的XML文檔轉化為輸入流,以便DOM解析器解析它

          6                   InputStream is=new FileInputStream("bin/library.xml");

          InputStream是一個接口。

          (4)解析XML文檔

          7                   saxparser.parse(is,new MySAXHandler());

          后面就不用看了,都是些沒用的代碼(相對而言),夠簡單的吧!

          注意了,我們新建了一個實例new MySAXHandler()這個實例里面又有什么東西呢?

          這個實例就是SAX的精華所在。我們使用SAX解析器時,必須實現內容處理器ContentHandler接口中的一些回調方法,然而我們不須要全部地實現這些方法,還好,我們有org.xml.sax.helpers.DefaultHandler類,看它的類申明:

          public class DefaultHandler

          implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler

          實現了這么多接口啊,其它的先不管了,至少它實現了ContentHandler這一接口。

          好了,看看這個類有些什么吧?下面是它的Java代碼!

          public class MySAXHandler extends DefaultHandler {

                 boolean hasAttribute=false;

                 Attributes attributes=null;

                 /* (非 Javadoc)

                  * @see org.xml.sax.helpers.DefaultHandler#startDocument()

                  */

                 public void startDocument() throws SAXException {

                         System.out.println("文檔開始打印了");

                 }

                 /* (非 Javadoc)

                  * @see org.xml.sax.helpers.DefaultHandler#endDocument()

                  */

                 public void endDocument() throws SAXException {

                        System.out.println("文檔打印結束了");

                 }

                 /* (非 Javadoc)

                  * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)

                  */

                 public void startElement(String uri, String localName, String qName,

                               Attributes attributes) throws SAXException {

                        if(qName.equals("books")){

                               return;

                        }

                        if(qName.equals("book")){

                               System.out.println(attributes.getQName(0)+attributes.getValue(0));

                        }

                        if(attributes.getLength()>0){

                               this.attributes=attributes;

                               this.hasAttribute=true;

                        }

                 }

                 /* (非 Javadoc)

                  * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)

                  */

                 public void endElement(String uri, String localName, String qName)

                               throws SAXException {

                        if(hasAttribute&&(attributes!=null)){

                               for(int i=0;i<attributes.getLength();i++){

                                      System.out.println(attributes.getQName(0)+attributes.getValue(0));

                               }

                        }

                 }

                 /* (非 Javadoc)

                  * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)

                  */

                 public void characters(char[] ch, int start, int length)

                               throws SAXException {

                        System.out.println(new String(ch,start,length));

                 }

           

           

          }

          不要看它一大堆,我一一分解給大家看。我們說SAX是基于事件的API,我們這個類實到了ContentHandler接口中的如下方法:

          (1)startDocument()  用于處理文檔解析開始事件

               public void startDocument() throws SAXException {

                         System.out.println("文檔開始打印了");

                  }

          (2)endDocument()  用于處理文檔解析結束事件

                public void endDocument() throws SAXException {

                        System.out.println("文檔打印結束了");

                  }

          (3)startElement  用于處理元素開始事件

               public void startElement(String uri, String localName, String qName,

                               Attributes attributes) throws SAXException {

                        if(qName.equals("books")){

                               return;

                        }

                        if(qName.equals("book")){

                               System.out.println(attributes.getQName(0)+attributes.getValue(0));

                        }

                        if(attributes.getLength()>0){

                               this.attributes=attributes;

                               this.hasAttribute=true;

                        }

                 }

          第二個參數String qName表示這個元素的名字,如:

          根節點 <books></books> 它的qName為“books”

          最底層節點 <price>jjjjjj</price> 它的qName為“price”

          知道這一點上面程序就好解釋了,當遇到根元素“books”時就什么也不做跳過,當遇到“book”元素時就打出它的屬性(它只有一個屬性<book email="zhoujunhui"></book>)。

          當是其它節點時(這下只剩下最底層的兩個節點“name”和“price”了),就把它的屬性取出來存到this.attributes域中,以后中元素結束事件好處理。

          (4)endElement 用于處理元素結束事件

               public void endElement(String uri, String localName, String qName)

                               throws SAXException {

                        if(hasAttribute&&(attributes!=null)){

                               for(int i=0;i<attributes.getLength();i++){

                                      System.out.println(attributes.getQName(0)+attributes.getValue(0));

                               }

                        }

                 }

          代碼的作用是如果這個元素的屬性不為空(hasAttribute&&(attributes!=null)),就把它們打印出來。

          (5)characters(char[] ch, int start, int length) 處理元素字符的內容

                        public void characters(char[] ch, int start, int length)

                               throws SAXException {

                        System.out.println(new String(ch,start,length));

                 }

          我們只用了這么幾個事件,其它還有其的的一些事件,我們只要看一下ContentHandler這個接口就行了,如:

          (6)startPrefixMapping(String prefix,String URI) 處理前綴映射開始事件,參數表示前綴名稱和所指向的URI

          (7)endPrefixMapping(String prefix,String URI) 處理前綴映射結束事件,參數表示前綴名稱和所指向的URI

          (8)ignorableWhitespace(Char[] ch,int start,int length) 處理元素中可忽略的空格

          (9)processingInstruction(String target,String data) 處理解析中產生的處理指令事件。

          posted on 2010-03-17 16:20 小菜毛毛 閱讀(2490) 評論(0)  編輯  收藏 所屬分類: XML

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 延安市| 自贡市| 寻甸| 普宁市| 石首市| 达孜县| 广州市| 茶陵县| 定襄县| 云龙县| 彰化市| 辉南县| 沈阳市| 古交市| 库伦旗| 东城区| 塔城市| 阿图什市| 读书| 博湖县| 青川县| 浦江县| 肃宁县| 茂名市| 庆安县| 资阳市| 莆田市| 科尔| 鱼台县| 磴口县| 平江县| 海淀区| 鄱阳县| 丰都县| 澳门| 满城县| 贞丰县| 上虞市| 平原县| 沂水县| 闽侯县|