Jaxp :Dom解析Xml文檔和SAX解析Xml文檔學習筆記

本文查閱方法:
    一、查閱目錄 —— 查閱本文目錄,肯定想要查閱的目錄標題
    二、快捷「查找」 —— 在當前瀏覽器頁面,按鍵 「Ctrl+F」 按鍵組合,開啓瀏覽器的查找功能,
             在查找搜索框中 輸入須要查閱的 目錄標題,即可以直接到達 標題內容 的位置。
    三、學習小結 —— 文中的學習小結內容,是筆者在學習以後總結出的,開發時可直接參考其進行應用開發的內容, 進一步加快了本文的查閱 速度。(水平有限,僅供參考。)
 html


 

 

 

本文目錄 java

 

  學習小結node

 

  一、JAXP概述程序員

 

  二、得到JAXP中的DOM解析器 web

 

  三、使用DOM解析Xml文檔 編程

 

  四、寫回數據/更新XML文檔瀏覽器

 

  五、DOM編程中的幾個名詞術語app

 

  六、DOM方式解析XML文件——流程範例Demodom

         A.DOM解析——得到Dom解析器:
         B.更新/寫回數據到原Xml文檔。(共三個步驟)
         C.遍歷全部節點
         D.查找某一個節點
         E.向xml文檔中添加新節點
         F.讀取指定標籤屬性的值:
         G.向xml文檔中指定位置上添加新節點
         H.向xml文檔中指定節點添加屬性
         I.刪除xml文檔中的指定節點
         J.刪除2: 刪除指定節點所在的父結點
         K.更新指定節點的文本內容ide

 

  七、Jaxp的SAX解析方式概述

 

  八、SAX解析原理剖析

 

  九、JDK文檔中對Sax解析方式的描述(圖解)

 

  十、SAX方式解析XML文檔的流程

         (1)使用SAX解析Xml文檔
         (2)樣例Demo1:編寫處理器——獲取整個xml文檔內容的處理器
         (3)樣例Demo2:編寫處理器—— 獲取到指定位置序列標籤的值 以及屬性值
         (4)樣例Demo3:編寫處理器——  把Xml文檔的數據封裝到JavaBean的處理器

 

  十一、編寫SAX處理器的流程與注意事項:

 

  十二、SAX 方式解析XML文件——流程範例Demo

 

 

 相關文章
    XML文檔語法 學習筆記
        地址:http://even2012.iteye.com/blog/1828064

    DTD約束 —— Xml文檔 約束技術 學習筆記
        地址:http://even2012.iteye.com/blog/1828290

    Schama —— Xml文檔約束技術 學習筆記
        地址:http://even2012.iteye.com/blog/1832073

    Dom4j 解析Xml文檔及 XPath查詢  學習筆記
        地址:http://even2012.iteye.com/blog/1832068

    Jaxp :Dom解析Xml文檔和SAX解析Xml文檔學習筆記
        地址:http://even2012.iteye.com/blog/1829981


 

 

 

學習小結

 

(1)Jaxp —— Dom 解析Xml文檔流程[共三個大步驟]

 

    A. 解析XML文檔:            

 

         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    //獲得工廠。

 

         DocumentBuilder builder = factory.newDocumentBuilder();                //獲得Dom解析器。

 

         Document document = builder.parse("src/book.xml");                    //獲得Dom文檔。

 

    B. Dom編程:對Dom樹中的Node、Element、Text、Attr等元素進行增、刪、改、查的操做

 

                a. 得到目標節點:Node node=document.getElementsByTagName.item(0); 

 

                b. 應用該節點進行各類CRUD的操做。

 

                【備註:重點是先獲取超級父類Node節點,進行操做,找不到合適的操做方法時,

 

                        可將其強轉成其餘對應的子節點,應用子類中更多的、有針對性的方法進行操做。】

 

    C. 更新/寫回 XMl文檔:

 

            TransformerFactory factory = TransformerFactory.newInstance();       //獲得工廠。   

 

            Transformer tf = factory.newTransformer();                        //獲得轉換器。 

 

            tf.transform(new DOMSource(document),       //實例對象document是原來解析得到Dom對象。

 

                     new StreamResult(new FileOutputStream("src/book.xml")));   //輸出到目標文件。

 

 

 

(2)Jaxp —— SAX解析Xml文檔流程。[共兩個大步驟]

 

    A. 使用SAX解析Xml文檔    

 

            SAXParserFactory factory = SAXParserFactory.newInstance();   //1.建立產生解析器的工廠     

 

            SAXParser parser = factory.newSAXParser();                   //2.建立解析器     

 

            XMLReader reader = parser.getXMLReader();                    //3.獲得xml文檔讀取器     

 

            reader.setContentHandler(new BookNameHandler());             //4.爲讀取器設置內容處理器     

 

            reader.parse("src/book.xml");                                //5.利用讀取器解析xml文檔       

 

    B. 編寫處理器——實現所須要的功能。

 

            a. 新建類,並繼承DefaultHandler 類

 

            b. 覆蓋startElement(...)、characters(...)、endElement(...) 這三個方法,並在裏面編寫代碼實現功能。

 

 

 


 

 

 

 

 

一、JAXP概述

 

    JAXP 開發包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包組成

 

    在 javax.xml.parsers 包中,定義了幾個工廠類,程序員調用這些工廠類,能夠獲得對xml文檔進行解析的 DOM 或 SAX 的解析器對象。

 

    【小知識:改JVM虛擬內存(默認值:64m),防止Dom解析時形成內存溢出】

 

            命令行: java -Xmx566m

 

            MyEclipse--》VM參數:-Xmx566m

 


 

 

 

二、得到JAXP中的DOM解析器 

 

    javax.xml.parsers 包中的DocumentBuilderFactory用於建立DOM模式的解析器對 象 , DocumentBuilderFactory是一個抽象工廠類,它不能直接實例化,但該類提供了一個newInstance()靜態方法 ,這 個方法會根據本地平臺默認安裝的解析器,自動建立一個工廠的對象並返回。

 


 

 

 

三、使用DOM解析Xml文檔

 

    a. 調用 DocumentBuilderFactory.newInstance() 方法獲得建立 DOM 解析器的工廠。 

 

    b. 調用工廠對象的 newDocumentBuilder()方法獲得 DOM 解析器對象。 

 

    c. 調用 DOM 解析器對象的 parse() 方法解析 XML 文檔,獲得表明整個文檔的 Document 對象,進而能夠利用DOM特性對整個XML文檔進行操做了。

 

    本例Demo見:標題「 七、DOM方式解析XML文件」 中的範例

 

 

 


 

 

 

四、寫回數據/更新XML文檔

 

    javax.xml.transform包中的Transformer類用於把表明XML文件的Document對象轉換爲某種格式後進行輸出,

 

        例如把xml文件應用樣式表後轉成一個html文檔。利用這個對象,固然也能夠把Document對象又從新寫入到一個XML文件中。

 

    (1)Transformer類經過transform(...)方法完成轉換操做,該方法接收一個源和一個目的地。

 

    (2)源document:javax.xml.transform.dom.DOMSource類來關聯要轉換的document對象, 

 

    (3)目的地文件:用javax.xml.transform.stream.StreamResult 對象來表示數據的目的地。

 

    (4)Transformer對象經過TransformerFactory得到。

 

    本例Demo見:標題「 七、DOM方式解析XML文件」 中的範例

 

 

 


 

  

 

五、DOM編程中的幾個名詞術語

 

    (1)DOM模型(document object model)

 

    (2)節點類型(Node對象)

 

        a.​DOM解析器在解析XML文檔時,會把文檔中的全部元素,按照其出現的層次關係,解析成一個個Node對象(節點)。 

 

        b.Node對象提供了一系列常量來表明結點的類型,當開發人員得到某個Node類型後,就能夠把Node節點轉換成相應的節點對象(Node的子類對象,如:Element,Attr,Text等),以便於調用其特有的方法。(查看API文檔) 

 

        c.Node對象提供了相應的方法去得到它的父結點或子結點。編程人員經過這些方法就能夠讀取整個XML文檔的內容、或添加、修改、刪除XML文檔的內容了。

 

    (3)在dom中,節點之間關係以下:

 

        A. parent ———— 位於一個節點之上的節點是該節點的父節點(parent)

 

        B. children ——— 一個節點之下的節點是該節點的子節點(children) 

 

        C. sibling  ——— 同一層次,具備相同父節點的節點是兄弟節點(sibling[ˈsɪblɪŋ]) 

 

        D. descendant —— 一個節點的下一個層次的節點集合是節點後代(descendant[diˈsendənt] )

 

        E. ancestor ——— 父、祖父節點及全部位於節點上面的,都是節點的祖先(ancestor[ˈænsistə] ) 

 

   

 

 

 


 

 

 

 

 

六、DOM方式解析XML文件——流程範例Demo

 

    A.DOM解析——得到Dom解析器:

 

      Demo:        

 

        //獲得dom解析器(共三個步驟)

 

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();    //獲得工廠。

 

            DocumentBuilder builder = factory.newDocumentBuilder();                //獲得Dom解析器。

 

            Document document = builder.parse("src/book.xml");                    //獲得Dom文檔。

 

 

 

    B.更新/寫回數據到原Xml文檔。(共三個步驟) 

 

        Demo:

 

        //把內存中更新後對象樹,從新定回到xml文檔中

 

            TransformerFactory factory = TransformerFactory.newInstance();       //獲得工廠。   

 

            Transformer tf = factory.newTransformer();                        //獲得轉換器。 

 

            tf.transform(new DOMSource(document),       //實例對象document是原來解析得到Dom對象。

 

                     new StreamResult(new FileOutputStream("src/book.xml")));   //輸出到目標文件。

 

                                

 

    C.遍歷全部節點

 

      Demo:

 

          @Test

 

          public void listXml() throws ParserConfigurationException, SAXException, Exception{

 

                list(document);

 

          }         

 

          public void list(Node node){    

 

                System.out.println(node.getNodeName());

 

                NodeList list = node.getChildNodes();

 

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

 

                      Node child = list.item(i);

 

                      list(child);

 

                }

 

          }

 

        

 

   D.查找某一個節點 

 

      Demo:

 

        //讀取書名節點的值:<書名>javaweb開發</書名>

 

          @Test

 

          public void test1(){

 

            //獲得dom解析器: 略... 

 

            Node node = document.getElementsByTagName("書名").item(0);

 

            String value = node.getTextContent();

 

            System.out.println(value);

 

          }

 

 

 

    E. 向xml文檔中添加新節 

 

      Demo:        

 

          @Test

 

          public void test3() throws Exception{

 

            //獲得dom解析器: 略...

 

            //建立要掛的節點

 

            Element price = document.createElement("售價");

 

            price.setTextContent("59元");

 

            //把建立的結點掛到書節點下

 

            Node book = document.getElementsByTagName("書").item(0);

 

            book.appendChild(price);

 

         

 

            //把內存中更新後對象樹,從新定回到xml文檔中:略。。。

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));

 

          }

 

 

 

     F.讀取指定標籤屬性的值::

 

        Demo:     

 

          @Test  //<售價 type="rmb">39.00元</售價>

 

          public void test2(){

 

            //獲得dom解析器: 略... 

 

            Node node = document.getElementsByTagName("售價").item(0);

 

            Element price =  (Element) node;   //發現node知足不了,把node強轉成相應類型

 

            String attValue = price.getAttribute("type");

 

            System.out.println(attValue);

 

          }

 

  

 

    G.向xml文檔中指定位置上添加新節點

 

      Demo:

 

          @Test

 

          public void test4() throws Exception{

 

            //獲得dom解析器: 略...  

 

            //建立要添加的節點

 

            Element price = document.createElement("售價");

 

            price.setTextContent("59元"); 

 

            //獲得要向哪一個節點上掛子節點

 

            Node book = document.getElementsByTagName("書").item(0); 

 

            //向參考節點前,掛新節點

 

            book.insertBefore(price, document.getElementsByTagName("售價").item(0)); 

 

            //把內存中更新後對象樹,從新定回到xml文檔中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));         

 

          }

 

 

 

    H.向xml文檔中指定節點添加屬性

 

      Demo:

 

          @Test

 

          public void test5() throws Exception{

 

            //獲得dom解析器: 略...   

 

            //獲得要添加屬性的節點

 

            Element author = (Element) document.getElementsByTagName("做者").item(0);

 

            author.setAttribute("id", "12");  //向節點掛屬性 

 

            //把內存中更新後對象樹,從新定回到xml文檔中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));             

 

          }

 

  

 

    I.刪除xml文檔中的指定節點

 

      Demo:

 

          @Test

 

          public void test6() throws Exception{ 

 

            //獲得dom解析器: 略...   

 

            //獲得要刪除的節點

 

            Node price = document.getElementsByTagName("售價").item(0);

 

            //獲得要刪除的節點的父親

 

            Node parent = document.getElementsByTagName("書").item(0); 

 

            parent.removeChild(price); 

 

            //把內存中更新後對象樹,從新定回到xml文檔中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document),

 

                     new StreamResult(new FileOutputStream("src/book.xml")));

 

          }

 

 

 

    J.刪除2: 刪除指定節點所在的父結點

 

      Demo:

 

          @Test

 

          public void test7() throws Exception{ 

 

            //獲得dom解析器: 略...   

 

            //獲得要刪除的節點

 

            Node price = document.getElementsByTagName("售價").item(0);

 

            price.getParentNode().getParentNode().removeChild(price.getParentNode()); 

 

            //把內存中更新後對象樹,從新定回到xml文檔中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));

 

          }

 

 

 

    K.更新指定節點的文本內容:

 

      Demo:

 

          @Test

 

          public void test8() throws Exception{

 

            //獲得dom解析器: 略...  

 

            document.getElementsByTagName("售價").item(1).setTextContent("19元");

 

            //把內存中更新後對象樹,從新定回到xml文檔中

 

            TransformerFactory factory = TransformerFactory.newInstance();

 

            Transformer tf = factory.newTransformer();

 

            tf.transform(new DOMSource(document), 

 

                    new StreamResult(new FileOutputStream("src/book.xml")));

 

          } 

 

 

 

    G.附 book.xml 文件內容:

 

        <?xml version="1.0" encoding="UTF-8"?><書架>
         <書>
          <書名>javaweb開發</書名>
          <做者 id="12">張孝祥</做者>
          <售價>59元</售價>
          <售價 type="rmb">19元</售價> 
         </書> 
         <書>
          <書名>JavaScript網頁開發</書名>
          <做者>張孝祥</做者>
          <售價>28.00元</售價>
         </書>
        </書架>

 

 

 


 

 

 

 

 

七、Jaxp的SAX解析方式概述

 

    DOM 解析的缺點—— 在使用 DOM 解析 XML 文檔時,須要讀取整個 XML 文檔,在內存中構架表明整個 DOM 樹的Doucment對象,從而再對XML文檔進行 操做。此種狀況下,若是 XML 文檔特別大,就會消耗計算機的大量內存,而且容易致使內存溢出。     

 

    SAX解析的特色—— SAX解析容許在讀取文檔的時候,即對文檔進行處理,而沒必要等到整個文檔裝載完纔會文檔進行操做。

 


 

 

 

八、SAX解析原理剖析

 

    SAX採用事件處理的方式解析XML文件,利用 SAX 解析 XML 文檔,涉及兩個部分:解析器和事件處理器:

 

    (1)解析器——可使用JAXP的API建立,建立出SAX解析器後,就能夠指定解析器去解析某個XML文檔。解析器採用SAX方式在解 析某個XML文檔時,它只要解析到XML文檔的一個組成部分,都會去調用事件處理器的一個方法,解析器在調用事件處理器的方法時,會把當前解析到的xml 文件內容做爲方法的參數傳遞給事件處理器。

 

    (2)事件處理器——由程序員編寫,程序員經過事件處理器中方法的參數,就能夠很輕鬆地獲得sax解析器解析到的數據,從而能夠決定如何對數據進行處理。

 


 

 

 

九、JDK文檔中對Sax解析方式的描述(圖解)

 

    備註:閱讀ContentHandler API文檔,經常使用方法:startElement、endElement、characters

 


             
 


 

 

十、SAX方式解析XML文檔的流程

 

    (1)使用SAXParserFactory建立SAX解析工廠

 

        SAXParserFactory spf = SAXParserFactory.newInstance();

 

    (2) 經過SAX解析工廠獲得解析器對象    

 

        SAXParser sp = spf.newSAXParser();

 

    (3) 經過解析器對象獲得一個XML的讀取器

 

        XMLReader xmlReader = sp.getXMLReader();

 

    (4) 設置讀取器的事件處理器

 

        xmlReader.setContentHandler(new BookParserHandler());    //實現不一樣的功能,須要設置可提供相應功能的處理。 

 

    (5) 解析xml文件  

 

        xmlReader.parse("book.xml");

 


 

 

 

十一、編寫SAX處理器的流程與注意事項:

 

    (1)編寫一個做爲處理器的類:實現接口ContentHandler  或者 繼承該接口的實現類:DefaultHandler

 

    (2)方式一:實現接口ContentHandler 

 

        實現該接口中全部的方法,經常使用的方法是:startElement()、endElement()、characters(). 

 

        缺點:須要在類中實現其所有方法(包括不須要使用的方法),是類中代碼顯得很亂。

 

    (3)方式二:繼承該接口的實現類:DefaultHandler 

 

        僅須要覆蓋 編程須要使用的方法,其餘方法能夠不覆蓋。

 

        優勢:類中僅僅包含所須要的方法,顯得代碼簡潔,易於閱讀維護。

 

              覆蓋經常使用的方法是:startElement()、endElement()、characters().  

 

    (4)根據編程須要,在覆蓋的方法中編寫相應的程序代碼。

 

        本例實現代碼見下一標題:「1三、SAX 方式解析XML文件——流程範例Demo」。

 


 

 

 

十二、SAX 方式解析XML文件——流程範例Demo

 

    (1)使用SAX解析Xml文檔    

 

        SAXParserFactory factory = SAXParserFactory.newInstance();   //1.建立產生解析器的工廠     

 

        SAXParser parser = factory.newSAXParser();                   //2.建立解析器     

 

        XMLReader reader = parser.getXMLReader();                    //3.獲得xml文檔讀取器     

 

        reader.setContentHandler(new BookNameHandler());             //4.爲讀取器設置內容處理器     

 

        reader.parse("src/book.xml");                                //5.利用讀取器解析xml文檔 

 

  

 

    (2)樣例Demo1:編寫處理器——獲取整個xml文檔內容的處理器

 

        class ListHandler extends DefaultHandler{    //建立類,並繼承

 

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

 

                  Attributes atts) throws SAXException {

 

                        System.out.println("<" + name + ">");

 

              }

 

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

 

                  throws SAXException {

 

                        System.out.println("</" + name + ">");

 

              }

 

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

 

                  throws SAXException {

 

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

 

              }

 

        }

 

 

 

    (3)樣例Demo2:編寫處理器—— 獲取到指定位置序列《書名》標籤的值 以及屬性值

 

        class BookNameHandler extends DefaultHandler{ 

 

              private String currentTag;

 

              private int count;  //記住當前解析到了幾個書名標籤

 

              @Override

 

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

 

                  Attributes attributes) throws SAXException {

 

                    currentTag = name;

 

                    if("書名".equals(currentTag)){

 

                          count++;

 

                    }

 

                  //獲得標籤全部屬性

 

                  for(int i=0;attributes!=null && i<attributes.getLength();i++){  //nullP

 

                       String attName = attributes.getQName(i);

 

                       String attValue = attributes.getValue(i);

 

                       System.out.println(attName + "=" + attValue);

 

                  }

 

              }             

 

              @Override

 

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

 

                  throws SAXException {

 

                    if("書名".equals(currentTag) && count==1){    //指定位置序列 1

 

                          System.out.println(new String(ch,start,length));    //將獲得的標籤名及其屬性值打印。

 

                    }

 

              }             

 

              @Override

 

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

 

                  throws SAXException {

 

                    super.endElement(uri, localName, name);

 

              }

 

        }    

 

 

 

    (4)樣例Demo3:編寫處理器——  把書的數據封裝到javabean的處理器

 

        class BeanListHandler extends DefaultHandler{ 

 

              private List list = new ArrayList();

 

              private Book book;    //自定義JavaBean類

 

              private String currentTag;

 

              public List getBooks(){

 

                    return list;

 

              }

 

         

 

              @Override

 

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

 

                  Attributes attributes) throws SAXException {

 

                currentTag = name;

 

                if(name.equals("書")){

 

                  book = new Book();  //book.set

 

                }

 

              }

 

         

 

              @Override

 

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

 

                  throws SAXException {

 

                    if(currentTag!=null && currentTag.equals("書名")){

 

                          book.setBookname(new String(ch,start,length));

 

                    }

 

                    if(currentTag!=null && currentTag.equals("做者")){

 

                          book.setAuthor(new String(ch,start,length));

 

                    }

 

                    if(currentTag!=null && currentTag.equals("售價")){

 

                          book.setPrice(new String(ch,start,length));

 

                    }

 

              }

 

         

 

              @Override

 

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

 

                  throws SAXException {

 

                    if(name.equals("書")){

 

                          list.add(book);

 

                    }

 

                    currentTag = null;

 

              } 

 

        }

 

        附1:Domain類:Book.java

 

            public class Book {

 

                  private String bookname;

 

                  private String author;

 

                  private String price;

 

                  public String getBookname() {

 

                        return bookname;

 

                  }

 

                  public void setBookname(String bookname) {

 

                        this.bookname = bookname;

 

                  }

 

                  public String getAuthor() {

 

                        return author;

 

                  }

 

                  public void setAuthor(String author) {

 

                        this.author = author;

 

                  }

 

                  public String getPrice() {

 

                        return price;

 

                  }

 

                  public void setPrice(String price) {

 

                        this.price = price;

 

                  }  

 

            }

 

        附2:Xml文件:book.xml

 

            <?xml version="1.0" encoding="UTF-8"?> 

 

            <書架> 

 

              <書> 

 

                <書名 name="aaa">javaweb開發</書名>  

 

                <做者>張孝祥</做者>  

 

                <售價>39元</售價> 

 

              </書>  

 

              <書> 

 

                <書名>JavaScript網頁開發</書名>  

 

                <做者>張xx</做者>  

 

                <售價>890元</售價> 

 

              </書> 

 

            </書架>

相關文章
相關標籤/搜索