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