摘要:通過解析器獲取文檔對象后,開發(fā)人員可以很方便的對其進(jìn)行操作,如獲取更元素,獲取一個子元素,增加子元素,移除子元素。它并沒有為解析提供任何新功能,但是它為在獲取與解析器提供了更加直接的途徑。自身不包含解析器,默認(rèn)使用隨包一起發(fā)行的。
文章最初發(fā)表于我的個人博客非典型性程序猿
眾所周知,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平臺上第一個被廣泛使用的XML API。也就說它是為JAVA而出現(xiàn)的。目前已經(jīng)有多個語言版本,比如C++。
DOM是Documents Object Model的簡稱,與SAX不同的是,DOM是W3C的標(biāo)準(zhǔn),它出現(xiàn)的目的是為了實(shí)現(xiàn)一套跨平臺與語言的標(biāo)準(zhǔn)。
以上是它們之間的第一個不同。第二個,就是解析方式的不同。
SAX是基于事件解析,解析過程中根據(jù)目前的XML元素類型,調(diào)用用戶自己實(shí)現(xiàn)的回調(diào)方法(或著叫事件方法)來處理,如:startDocument();,startElement(); 。
SAX2.0中有4個核心接口:
org.xml.sax.ContentHander
org.xml.sax.ErrorHandler
org.xml.sax.DTDHandler
org.xml.sax.EntityResolver
實(shí)現(xiàn)這幾個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"));
基于事件處理的好處是,不需要等到整個XML文件被加載完成后在開始處理,而是加載到哪處理到哪。這樣便帶來了效率上的優(yōu)勢。但是其也有明顯的不足,第一個不足便是無法隨機(jī)訪問元素。如果你只想獲取第二元素的信息,那么你必須等到第一個元素處理完成后,第二個元素開始的時候。如果這時,你又需要返回第一個元素,那么對不起,已經(jīng)來不及了。SAX不會主動記憶或保存已處理過的元素(為了效率)。為了實(shí)現(xiàn)前面的需求,開發(fā)人員需要自己使用容器來保存處理過的元素,并且建立一個模型來表示XML的樹形結(jié)構(gòu)。這樣一來也就帶來了第二個缺點(diǎn),使用的復(fù)雜性。
再來說說DOM。DOM采用了解析方式是一次性加載整個XML文檔,在內(nèi)存中形成一個樹形的數(shù)據(jù)結(jié)構(gòu),這個數(shù)據(jù)結(jié)構(gòu)我們稱為文檔對象模型。通過DOM解析器獲取Documen文檔t對象后,開發(fā)人員可以很方便的對其進(jìn)行操作,如getDocumentElement();(獲取更元素),getFirstChild();獲取一個子元素,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是一次性加載整個XML文件到內(nèi)存, 如果XML文件非常龐大,構(gòu)建文檔樹的內(nèi)存與時間開銷會很大,且很有可能導(dǎo)致內(nèi)存溢出異常。
那么如何在SAX與DOM直接選擇呢?這取決于下面幾個因素:
應(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ù)中的少量部分會被使用,那么使用 SAX 來將該部分?jǐn)?shù)據(jù)提取到應(yīng)用程序中可能更好。 另一方面,如果您知道自己以后會回頭引用已處理過的大量信息,那么 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 來完成這個任務(wù),比如DOM4J與JDOM!
JAXP,全稱Java API for XML Processing,打開其為JDK的目錄:javax.xml.parsers, 你會發(fā)現(xiàn)它與SAX和DOM一樣只是一套API。實(shí)際上,JAXP出現(xiàn)時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)一套跨平臺與語言的標(biāo)準(zhǔn),因此使用它對于JAVA開發(fā)人員來說并不是特別的得心應(yīng)手,這時JDOM就出現(xiàn)了。
JDOM 的目的是成為 Java 特定文檔模型,它簡化與 XML 的交互并且比使用 DOM 實(shí)現(xiàn)更快。而且它是第一個 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 的一個分支。它合并了許多超出基本 XML 文檔表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文檔或流化文檔的基于事件的處理。它還提供了構(gòu)建文檔表示的選項(xiàng),它通過 DOM4J API 和標(biāo)準(zhǔn) DOM 接口具有并行訪問功能。
為支持所有這些功能,DOM4J 使用接口和抽象基本類方法。DOM4J 大量使用了 API 中的Collections 類,但是在許多情況下,它還提供一些替代方法以允許更好的性能或更直接的編碼方法。直接好處是,雖然 DOM4J 付出了更復(fù)雜的 API 的代價,但是它提供了比 JDOM 大得多的靈活性。在添加靈活性、XPath 集成和對大文檔處理的目標(biāo)時,DOM4J 的目標(biāo)與 JDOM 是一樣的:針對 Java開發(fā)者的易用性和直觀操作。它還致力于成為比 JDOM 更完整的解決方案,實(shí)現(xiàn)在本質(zhì)上處理所有Java/XML 問題的目標(biāo)。在完成該目標(biāo)時,它比 JDOM 更少強(qiáng)調(diào)防止不正確的應(yīng)用程序行為。
例子:
SAXReader reader = new SAXReader(false); Document doc = reader.read(in);
DOM4J 是一個非常非常優(yōu)秀的Java XML API,具有性能優(yōu)異、功能強(qiáng)大和極端易用使用的特點(diǎn),同時它也是一個開放源代碼的軟件。如今你可以看到越來越多的 Java 軟件都在使用 DOM4J 來讀寫 XML,特別值得一提的是連 Sun 的 JAXM 也在用 DOM4J。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/110335.html
摘要:通過解析器獲取文檔對象后,開發(fā)人員可以很方便的對其進(jìn)行操作,如獲取更元素,獲取一個子元素,增加子元素,移除子元素。它并沒有為解析提供任何新功能,但是它為在獲取與解析器提供了更加直接的途徑。自身不包含解析器,默認(rèn)使用隨包一起發(fā)行的。 showImg(/img/bVDhQE?w=888&h=220); 文章最初發(fā)表于我的個人博客非典型性程序猿 眾所周知,SAX與DOM是JAVA中兩大核心X...
摘要:解析獲取解析器獲取文檔獲取根節(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ù)超級干貨奉上,快快樂樂學(xué)。 大家好,樂字節(jié)的小樂又來了,Java技術(shù)分享哪里少的了小樂!上次我們說了可擴(kuò)展標(biāo)記語言XML之二:XML語言格式規(guī)范、文檔組成,本文將介紹重點(diǎn)——XML解析。sh...
摘要:它提供了一套非常省力的,可通過,以及類似于的操作方法來取出和操作數(shù)據(jù)。 XML:可擴(kuò)展標(biāo)記型語言 隨著json等一些技術(shù)的普及,似乎xml的路子越來越窄,雖然xml的一些功能被其他的一些技術(shù)代替,但是學(xué)習(xí)xml還是非常有必要,如果用xml存儲一些大量數(shù)據(jù),還是有一定優(yōu)勢的,就算你不管這些,但是現(xiàn)有的很多框架以及技術(shù)的配置文件都存在于xml中,最起碼你得對它的結(jié)構(gòu)以及一些基本用法有一定了...
閱讀 918·2021-10-13 09:39
閱讀 3571·2021-09-26 10:16
閱讀 2932·2019-08-30 15:54
閱讀 1071·2019-08-30 14:22
閱讀 2913·2019-08-29 15:39
閱讀 3290·2019-08-27 10:52
閱讀 839·2019-08-26 13:59
閱讀 1750·2019-08-26 12:20