Calvin's Tech Space

          成于堅忍,毀于浮躁

             :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理


          關(guān)于XML DOM模型更重要的參考資源:

          http://www.w3school.com.cn/xmldom/dom_nodes.asp

          一、前言
          用Java解析XML文檔,目前有以下方法:
                   首先是DOM,DOM 是用與平臺和語言無關(guān)的方式表示 XML 文檔的官方 W3C 標準。DOM 是以層次結(jié)構(gòu)組織的節(jié)點或信息片斷的集合。這個層次結(jié)構(gòu)允許開發(fā)人員在樹中尋找特定信息。分析該結(jié)構(gòu)通常需要加載整個文檔和構(gòu)造層次結(jié)構(gòu),然后才能做任何工作。由于它是基于信息層次的,因而 DOM 被認為是基于樹或基于對象的。DOM 以及廣義的基于樹的處理具有幾個優(yōu)點。    
              首先,由于樹在內(nèi)存中是持久的,因此可以修改它以便應(yīng)用程序能對數(shù)據(jù)和結(jié)構(gòu)作出更改。它還可以在任何時候在樹中上下導(dǎo)航,而不是像 SAX 那樣是一次性的處理。DOM 使用起來也要簡單得多。

            另一方面,對于特別大的文檔,解析和加載整個文檔可能很慢且很耗資源,因此使用其他手段來處理這樣的數(shù)據(jù)會更好。這些基于事件的模型,比如 SAX。 接著是 SAX這種處理的優(yōu)點非常類似于流媒體的優(yōu)點。分析能夠立即開始,而不是等待所有的數(shù)據(jù)被處理。而且,由于應(yīng)用程序只是在讀取數(shù)據(jù)時檢查數(shù)據(jù),因此不需要將數(shù)據(jù)存儲在內(nèi)存中。這對于大型文檔來說是個巨大的優(yōu)點。事實上,應(yīng)用程序甚至不必解析整個文檔;它可以在某個條件得到滿足時停止解析。一般來說,SAX 還比它的替代者 DOM 快許多 再接著是 JDOM JDOM 的目的是成為 Java 特定文檔模型,它簡化與 XML 的交互并且比使用 DOM 實現(xiàn)更快。由于是第一個 Java 特定模型,JDOM 一直得到大力推廣和促進。正在考慮通過“Java 規(guī)范請求 JSR-102”將它最終用作“Java 標準擴展”。從 2000 年初就已經(jīng)開始了 JDOM 開發(fā)。

            JDOM 與 DOM 主要有兩方面不同。首先,JDOM 僅使用具體類而不使用接口。這在某些方面簡化了 API,但是也限制了靈活性。第二,API 大量使用了 Collections 類,簡化了那些已經(jīng)熟悉這些類的 Java 開發(fā)者的使用。

            JDOM 文檔聲明其目的是“使用 20%(或更少)的精力解決 80%(或更多)Java/XML 問題”(根據(jù)學習曲線假定為 20%)。JDOM 對于大多數(shù) Java/XML 應(yīng)用程序來說當然是有用的,并且大多數(shù)開發(fā)者發(fā)現(xiàn) API 比 DOM 容易理解得多。JDOM 還包括對程序行為的相當廣泛檢查以防止用戶做任何在 XML 中無意義的事。然而,它仍需要您充分理解 XML 以便做一些超出基本的工作(或者甚至理解某些情況下的錯誤)。這也許是比學習 DOM 或 JDOM 接口都更有意義的工作。

            JDOM 自身不包含解析器。它通常使用 SAX2 解析器來解析和驗證輸入 XML 文檔(盡管它還可以將以前構(gòu)造的 DOM 表示作為輸入)。它包含一些轉(zhuǎn)換器以將 JDOM 表示輸出成 SAX2 事件流、DOM 模型或 XML 文本文檔。JDOM 是在 Apache 許可證變體下發(fā)布的開放源碼。 
              最后是 DOM4J http://dom4j.sourceforge.net/.雖然 DOM4J 代表了完全獨立的開發(fā)結(jié)果,但最初,它是 JDOM 的一種智能分支。它合并了許多超出基本 XML 文檔表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項,它通過 DOM4J API 和標準 DOM 接口具有并行訪問功能。從 2000 下半年開始,它就一直處于開發(fā)之中。

            為支持所有這些功能,DOM4J 使用接口和抽象基本類方法。DOM4J 大量使用了 API 中的 Collections 類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然 DOM4J 付出了更復(fù)雜的 API 的代價,但是它提供了比 JDOM 大得多的靈活性。

            在添加靈活性、XPath 集成和對大文檔處理的目標時,DOM4J 的目標與 JDOM 是一樣的:針對 Java 開發(fā)者的易用性和直觀操作。它還致力于成為比 JDOM 更完整的解決方案,實現(xiàn)在本質(zhì)上處理所有 Java/XML 問題的目標。在完成該目標時,它比 JDOM 更少強調(diào)防止不正確的應(yīng)用程序行為。

            DOM4J 是一個非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的 Java 軟件都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。 JDOM 和 DOM 在性能測試時表現(xiàn)不佳,在測試 10M 文檔時內(nèi)存溢出。在小文檔情況下還值得考慮使用 DOM 和 JDOM。雖然 JDOM 的開發(fā)者已經(jīng)說明他們期望在正式發(fā)行版前專注性能問題,但是從性能觀點來看,它確實沒有值得推薦之處。另外,DOM 仍是一個非常好的選擇。DOM 實現(xiàn)廣泛應(yīng)用于多種編程語言。它還是許多其它與 XML 相關(guān)的標準的基礎(chǔ),因為它正式獲得 W3C 推薦(與基于非標準的 Java 模型相對),所以在某些類型的項目中可能也需要它(如在 JavaScript 中使用 DOM)。

            SAX表現(xiàn)較好,這要依賴于它特定的解析方式。一個 SAX 檢測即將到來的XML流,但并沒有載入到內(nèi)存(當然當XML流被讀入時,會有部分文檔暫時隱藏在內(nèi)存中)。

            無疑,DOM4J是這場測試的獲勝者,目前許多開源項目中大量采用 DOM4J,例如大名鼎鼎的 Hibernate 也用 DOM4J 來讀取 XML 配置文件。如果不考慮可移植性,那就采用DOM4J吧!

                  使用基于事件的XML簡單API(Simple API for XML)稱為SAX和基于樹和節(jié)點的文檔對象模型(Document Object Module)稱為DOM。Sun公司提供了Java API for XML Parsing(JAXP)接口來使用SAX和DOM,通過JAXP,我們可以使用任何與JAXP兼容的XML解析器。
          JAXP接口包含了三個包:
          (1)org.w3c.dom W3C推薦的用于XML標準規(guī)劃文檔對象模型的接口。
          (2)org.xml.sax 用于對XML進行語法分析的事件驅(qū)動的XML簡單API(SAX)
          (3)javax.xml.parsers解析器工廠工具,程序員獲得并配置特殊的特殊語法分析器。

          二、前提

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

          三、使用DOM解析XML文檔

          我們現(xiàn)在來看看DOM是如何解析XML的吧!同樣的,我將從一個簡單的不能再簡單的例子來說明DOM是如何解析XML文檔的,先讓我們看看XML是什么內(nèi)容吧:

          <?xml version="1.0" encoding="gb2312"?>
          <books>
          <book email="zhoujunhui">
          <name>rjzjh</name>
          <price>jjjjjj</price>
          </book>
          </books>

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

          1 public class DomParse {
          2     public DomParse(){
          3        DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
          4        try {
          5            DocumentBuilder dombuilder=domfac.newDocumentBuilder();
          6            InputStream is=new FileInputStream("bin/library.xml");
          7            Document doc=dombuilder.parse(is);
          9            Element root=doc.getDocumentElement();
          10          NodeList books=root.getChildNodes();
          11          if(books!=null){
          12              for(int i=0;i<books.getLength();i++){
          13                  Node book=books.item(i);
          14                  if(book.getNodeType()==Node.ELEMENT_NODE){
          15                      String email=book.getAttributes().getNamedItem("email").getNodeValue();
          16                      System.out.println(email);
          17                      for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
          18                          if(node.getNodeType()==Node.ELEMENT_NODE){
          19                              if(node.getNodeName().equals("name")){
          20                                  String name=node.getNodeValue();
          21                                  String name1=node.getFirstChild().getNodeValue();
          22                                  System.out.println(name);
          23                                  System.out.println(name1);
          24                              }
          25                              if(node.getNodeName().equals("price")){
          26                                  String price=node.getFirstChild().getNodeValue();
          27             System.out.println(price);
          28               }
          29                          }
          30                      }
          31                  }
          32              }
          33        }
          34    } catch (ParserConfigurationException e) {
          35      e.printStackTrace();
          36    } catch (FileNotFoundException e) {
          37      e.printStackTrace();
          38    } catch (SAXException e) {
          39      e.printStackTrace();
          40    } catch (IOException e) {
          41      e.printStackTrace();
          42        }
          43    }
          44    public static void main(String[] args) {
          45        new DomParse();
          46    }
          47 }

          四、代碼解釋

          先看看這個程序引用類:
          import java.io.FileInputStream;
          import java.io.FileNotFoundException;
          import java.io.IOException;
          import java.io.InputStream;
          import javax.xml.parsers.DocumentBuilder;
          import javax.xml.parsers.DocumentBuilderFactory;
          import javax.xml.parsers.ParserConfigurationException;

          //下面主要是org.xml.sax包的類
          import org.w3c.dom.Document;
          import org.w3c.dom.Element;
          import org.w3c.dom.Node;
          import org.w3c.dom.NodeList;
          import org.xml.sax.SAXException;

          上面那么簡單的代碼一看就明白了,但是為了介紹個DOM編程的大概還是來看看這個程序吧:

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

          DocumentBuilderFactory domfac=DocumentBuilderFactory.newInstance();
          得到j(luò)avax.xml.parsers.DocumentBuilderFactory;類的實例就是我們要的解析器工廠

          (2)從DOM工廠獲得DOM解析器

          DocumentBuilder dombuilder=domfac.newDocumentBuilder();
          通過javax.xml.parsers.DocumentBuilderFactory實例的靜態(tài)方法newDocumentBuilder()得到DOM解析器

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

          InputStream is=new FileInputStream("bin/library.xml");
          InputStream是一個接口。

          (4)解析XML文檔的輸入流,得到一個Document

          Document doc=dombuilder.parse(is);
          由XML文檔的輸入流得到一個org.w3c.dom.Document對象,以后的處理都是對Document對象進行的

          (5)得到XML文檔的根節(jié)點

          Element root=doc.getDocumentElement();
          在DOM中只有根節(jié)點是一個org.w3c.dom.Element對象。

          (6)得到節(jié)點的子節(jié)點

          NodeList books=root.getChildNodes();
          for(int i=0;i<books.getLength();i++){
          Node book=books.item(i);
          }
          這是用一個org.w3c.dom.NodeList接口來存放它所有子節(jié)點的,還有一種輪循子節(jié)點的方法,后面有介紹

          (7)取得節(jié)點的屬性值

          String email=book.getAttributes().getNamedItem("email").getNodeValue();
          System.out.println(email);
          注意,節(jié)點的屬性也是它的子節(jié)點。它的節(jié)點類型也是Node.ELEMENT_NODE

          (8)輪循子節(jié)點

          for(Node node=book.getFirstChild();node!=null;node=node.getNextSibling()){
              if(node.getNodeType()==Node.ELEMENT_NODE){
                  if(node.getNodeName().equals("name")){
                      String name=node.getNodeValue();
                      String name1=node.getFirstChild().getNodeValue();
                      System.out.println(name);
                      System.out.println(name1);
                  }
              if(node.getNodeName().equals("price")){
                  String price=node.getFirstChild().getNodeValue();
                  System.out.println(price);
              }
          }

          這段代碼的打印輸出為:
          null
          alterrjzjh
          jjjjjj
          從上面可以看出
          String name=node.getNodeValue();  是一個空值。而
          String name1=node.getFirstChild().getNodeValue(); 才是真正的值,這是因為DOM把<name> rjzjh</name>也當作是兩層結(jié)構(gòu)的節(jié)點,其父節(jié)點為<name>節(jié)點本身,且它只有一個子節(jié)點(如果有屬性的話就不止 一個了!),子節(jié)點是它的值“rjzjh”,所以我們看到上面的結(jié)果。
          還有,子節(jié)點的節(jié)點類型也是Node.ELEMENT_NODE型的,node.getNextSibling()方法是取下一個相鄰的節(jié)點。

          五、DOM結(jié)點

          DOM是一些節(jié)點的集合,由于文檔中可能包含有不同類型的信息,所以定義了幾種不同類型的節(jié)點。DOM中最常見的節(jié)點類型有:

          (1)元素:
          元素是XML的基本構(gòu)件。元素的子節(jié)點可以是其它元素、文本節(jié)點或兩者都有。元素節(jié)點還可以只含有屬性這一唯一類型的節(jié)點。

          (2)屬性:
          屬性節(jié)點包含關(guān)于元素節(jié)點的信息,但它不是元素的子節(jié)點

          (3)文本:
          文本節(jié)點文本信息,或干脆是空白的文本。

          注意:空白文本,回車換行也是文本節(jié)點

          (4)文檔:
          文檔節(jié)點是整個文檔中所有其它節(jié)點的父節(jié)點
          元素是一種很重要的類型節(jié)點,元素節(jié)點可以是其他節(jié)點的容器。

          六、DOM解析XML文檔的步驟:

          主要幾步見第四點的(1),(2),(3),(4)步驟

          (本文轉(zhuǎn)自http://blog.csdn.net/xiangfu_txe/archive/2008/02/02/2077647.aspx)

          posted on 2009-09-08 18:47 calvin 閱讀(1090) 評論(1)  編輯  收藏 所屬分類: Java

          Feedback

          # re: XML文檔解析及用dom解析xml 2013-01-13 18:22 W3School官網(wǎng)
          http://www.w3school.org.cn/xmldom/dom_nodes.asp  回復(fù)  更多評論
            

          主站蜘蛛池模板: 乌兰县| 衡东县| 都匀市| 武穴市| 海林市| 谢通门县| 天台县| 通许县| 宣恩县| 安顺市| 天峻县| 泊头市| 肃南| 乌鲁木齐市| 屏南县| 颍上县| 介休市| 青河县| 聂拉木县| 镇巴县| 东平县| 铜陵市| 手游| 宜州市| 忻州市| 开远市| 金寨县| 都江堰市| 新兴县| 土默特左旗| 奎屯市| 嘉祥县| 区。| 河东区| 仪征市| 沂源县| 封丘县| 金川县| 韩城市| 方山县| 唐山市|