摘要:通過解析器獲取文檔對象后,開發人員可以很方便的對其進行操作,如獲取更元素,獲取一個子元素,增加子元素,移除子元素。它并沒有為解析提供任何新功能,但是它為在獲取與解析器提供了更加直接的途徑。自身不包含解析器,默認使用隨包一起發行的。
文章最初發表于我的個人博客非典型性程序猿
眾所周知,SAX與DOM是JAVA中兩大核心XML解析API類庫,而JAXP,JDOM與DOM4J都是基于這兩大核心API而衍生出來的。今日興起看了看相關資料,寫篇文章總結總結^.^。
SAX與DOM首先需要說明白的是SAX與DOM的關系。
SAX與DOM都是底層API,在JDK中他們的包路徑分別為:org.xml.sax與org.w3c.dom。自JDK1.5開始,JDK中自帶的實現為Apache的xerces(位于com.sun.org.apache.xerces.internal.parsers下)。
SAX是Simple API for XML的簡稱,它是在JAVA平臺上第一個被廣泛使用的XML API。也就說它是為JAVA而出現的。目前已經有多個語言版本,比如C++。
DOM是Documents Object Model的簡稱,與SAX不同的是,DOM是W3C的標準,它出現的目的是為了實現一套跨平臺與語言的標準。
以上是它們之間的第一個不同。第二個,就是解析方式的不同。
SAX是基于事件解析,解析過程中根據目前的XML元素類型,調用用戶自己實現的回調方法(或著叫事件方法)來處理,如:startDocument();,startElement(); 。
SAX2.0中有4個核心接口:
org.xml.sax.ContentHander
org.xml.sax.ErrorHandler
org.xml.sax.DTDHandler
org.xml.sax.EntityResolver
實現這幾個Handler,然后調用解析器相應的set方法注冊給解析器,就可以完成各種元素的解析與處理。 對應的注冊進解析器的方法分別是:
parser.setContentHandler(ContentHander handler)
parser.setErrorHandler(ErrorHandler handler)
parser.setDTDHandler(DTDHandler handler)
完整例子:
DefaultHandler handler=new XmlParserHandler();//DefaultHandler已經實現了全部org.xml.sax.ContentHandler, //org.xml.sax.ErrortHandler,org.xml.sax.DTDHandler和org.xml.sax.EntityHandler接口 XMLReader xr=XMLReaderFactory.createXMLReader();//獲取解析器實例 xr.setContentHandler(handler);//設置處理類 xr.setErrorHandler(handler); xr.setDTDHandler(handler); xr.setFeature("http://xml.org/sax/features/validation", true);//開啟DTD驗證 xr.setFeature("http://apache.org/xml/features/validation/schema", true);//開啟SCHMAE驗證 xr.parse(new InputSource("F:/Work/Workspace/XmlStudy/test.xml"));
基于事件處理的好處是,不需要等到整個XML文件被加載完成后在開始處理,而是加載到哪處理到哪。這樣便帶來了效率上的優勢。但是其也有明顯的不足,第一個不足便是無法隨機訪問元素。如果你只想獲取第二元素的信息,那么你必須等到第一個元素處理完成后,第二個元素開始的時候。如果這時,你又需要返回第一個元素,那么對不起,已經來不及了。SAX不會主動記憶或保存已處理過的元素(為了效率)。為了實現前面的需求,開發人員需要自己使用容器來保存處理過的元素,并且建立一個模型來表示XML的樹形結構。這樣一來也就帶來了第二個缺點,使用的復雜性。
再來說說DOM。DOM采用了解析方式是一次性加載整個XML文檔,在內存中形成一個樹形的數據結構,這個數據結構我們稱為文檔對象模型。通過DOM解析器獲取Documen文檔t對象后,開發人員可以很方便的對其進行操作,如getDocumentElement();(獲取更元素),getFirstChild();獲取一個子元素,appendChild();增加子元素,removeChild();移除子元素。因此,使用DOM可以很方便對XML中的數據進行獲取與修改,而不需要像SAX一樣自己設計模型保存獲取的數據。
完整例子:
DOMParser dp=new DOMParser(); dp.parse(new InputSource("e:/test.xml")); Document doc=dp.getDocument(); Element rootElemet=doc.getDocumentElement(); NodeList list=rootElemet.getChildNodes();
跟重要的一點是,在DOM中所有Element都是Node,這意味著,我們不需要明確知道文檔的結構就可以操作它。我們可以判斷當前獲取到的任意Node對象類型來做不同操作。主要Node類型有:
- Node.DOCUMENT_NODE - Node.ELEMENT_NODE - Node.TEXT_NODE - Node.CDATA_SECTION_NODE - Node.PROCESSING_INSTRUCTION_NODE - Node.ENTITY_REFERENCE_NODE - Node.DOCUMENT_TYPE_NODE
但是,由于DOM是一次性加載整個XML文件到內存, 如果XML文件非常龐大,構建文檔樹的內存與時間開銷會很大,且很有可能導致內存溢出異常。
那么如何在SAX與DOM直接選擇呢?這取決于下面幾個因素:
應用程序的目的:如果打算對數據作出更改并將它輸出為 XML,那么在大多數情況下,DOM 是適當的選擇。并不是說使用 SAX 就不能更改數據,但是該過程要復雜得多,因為您必須對數據的一份拷貝而不是對數據本身作出更改。
數據容量: 對于大型文件,SAX 是更好的選擇。
數據將如何使用:如果只有數據中的少量部分會被使用,那么使用 SAX 來將該部分數據提取到應用程序中可能更好。 另一方面,如果您知道自己以后會回頭引用已處理過的大量信息,那么 SAX 也許不是恰當的選擇。
對速度的需要: SAX 實現通常要比 DOM 實現更快。
JAXP,JDOM與DOM4J JAXPSAX 和 DOM 不是相互排斥的,記住這點很重要。您可以使用 DOM 來創建 SAX 事件流,也可以使用 SAX 來創建 DOM 樹。事實上,用于創建 DOM 樹的大多數解析器實際上都使用 SAX 來完成這個任務,比如DOM4J與JDOM!
JAXP,全稱Java API for XML Processing,打開其為JDK的目錄:javax.xml.parsers, 你會發現它與SAX和DOM一樣只是一套API。實際上,JAXP出現時SUN公司為了彌補JAVA在XML標準制定上的空白而制定的一套JAVA XML標準API。它并沒有為JAVA解析XML提供任何新功能,但是它為在JAVA獲取SAX與DOM解析器提供了更加直接的途徑。它封裝了SAX與DOM兩種接口,并在SAX與DOM的基礎之上,作了一套比較簡單的api以供開發。
例如:JAXP獲取SAX解析器:
SAXParserFactory factory=SAXParserFactory.newInstance(); SAXParser parser=factory.newSAXParser(); parser.parse("F:/Work/Workspace/xiongqi/XmlStudy/test.xml", handler);
獲取DOM解析器:
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance(); DocumentBuilder builder= factory.newDocumentBuilder(); Document document= builder.parse("F:/Work/Workspace/xiongqi/XmlStudy/test.xml");
在 JAXP 的早期版本中,自帶解析器的實現為 Apachede 的Crimson,在 JAXP 的新版本中 (包括在 JDK 中) ,Sun 已經重新包裝了 Apache Xerces 做為解析器的實現。
JDOM由于DOM是為了實現一套跨平臺與語言的標準,因此使用它對于JAVA開發人員來說并不是特別的得心應手,這時JDOM就出現了。
JDOM 的目的是成為 Java 特定文檔模型,它簡化與 XML 的交互并且比使用 DOM 實現更快。而且它是第一個 Java 特定模型。與DOM相比較,首先,JDOM 僅使用具體類而不使用接口。這在某些方面簡化了API,但是也限制了靈活性。第二,API 大量使用了 Collections 類,相對于dom中的Node,簡化了那些已經熟悉這些類的Java 開發者的使用。JDOM 自身不包含解析器,默認使用隨jar包一起發行的pache Xerces。
例子:
SAXBuilder builder = new SAXBuilder(false); Document doc = builder.build(in);
從上面代碼中可以看出,JDOM使用SAX2 解析器來解析和驗證輸入 XML 文檔,然后構建Doucment對象。
DOM4JDOM4J 最初是 JDOM 的一個分支。它合并了許多超出基本 XML 文檔表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構建文檔表示的選項,它通過 DOM4J API 和標準 DOM 接口具有并行訪問功能。
為支持所有這些功能,DOM4J 使用接口和抽象基本類方法。DOM4J 大量使用了 API 中的Collections 類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然 DOM4J 付出了更復雜的 API 的代價,但是它提供了比 JDOM 大得多的靈活性。在添加靈活性、XPath 集成和對大文檔處理的目標時,DOM4J 的目標與 JDOM 是一樣的:針對 Java開發者的易用性和直觀操作。它還致力于成為比 JDOM 更完整的解決方案,實現在本質上處理所有Java/XML 問題的目標。在完成該目標時,它比 JDOM 更少強調防止不正確的應用程序行為。
例子:
SAXReader reader = new SAXReader(false); Document doc = reader.read(in);
DOM4J 是一個非常非常優秀的Java XML API,具有性能優異、功能強大和極端易用使用的特點,同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的 Java 軟件都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/110335.html
摘要:通過解析器獲取文檔對象后,開發人員可以很方便的對其進行操作,如獲取更元素,獲取一個子元素,增加子元素,移除子元素。它并沒有為解析提供任何新功能,但是它為在獲取與解析器提供了更加直接的途徑。自身不包含解析器,默認使用隨包一起發行的。 showImg(/img/bVDhQE?w=888&h=220); 文章最初發表于我的個人博客非典型性程序猿 眾所周知,SAX與DOM是JAVA中兩大核心X...
摘要:解析獲取解析器獲取文檔獲取根節點獲取根節點下所有的子節點,也可以根據標簽名稱獲取指定的直接點獲取元素的名稱和里面的文本創建創建節點創建屬性設置文本設置關系關于解析先講到這里了,請繼續關注樂字節,后續超級干貨奉上,快快樂樂學。 大家好,樂字節的小樂又來了,Java技術分享哪里少的了小樂!上次我們說了可擴展標記語言XML之二:XML語言格式規范、文檔組成,本文將介紹重點——XML解析。sh...
閱讀 877·2021-10-13 09:39
閱讀 3531·2021-09-26 10:16
閱讀 2860·2019-08-30 15:54
閱讀 1037·2019-08-30 14:22
閱讀 2885·2019-08-29 15:39
閱讀 3253·2019-08-27 10:52
閱讀 809·2019-08-26 13:59
閱讀 1702·2019-08-26 12:20