Sun這一家公司一直蠻注意xml的發展,我們可以 看到java這個語言跟xml結合得蠻不錯的。最近sun release 了一個XML pack,裡面包含了JAXM, JXAP, JAXR, JAXRPC 這幾個XML方面的API,這次我們就來介紹一下其中用來做 XML parsing的API JAXP。 JAXP這一組API在Sun的所有有關XML的API中,是最早 開始發展的,目前的版本是JAXP 1.2,已經算是規格蠻穩定 的一組API,而且目前是採用將API的規格和底下parsing引擎 分開的設計方式,程式設計人員可以自行選擇合適的引擎但 又不會違背規格,感覺上是蠻體貼的一項設計。實際上,JAXP 1.2 以及XML pack裡面所搭的的引擎配合起來可以做XML parsing 以及XSLT的處理,不過這篇心得的重點會先放在XML的parsing上面。 在JAXP裡面,XML parsing的方式有兩種,一種稱為DOM parsing, 一種稱為SAX parsing,其中DOM parsing會將整個XML文件讀入, 並在記憶體裡面根據W3C的DOM規格建立一個tree的資料結構, 有了這樣一個結構,之後可以作各種搜尋,也可以節取出子樹 來做應用,相當的方便,而且要定位XML文件的任何一個node也比較 容易,不過缺點是第一次查詢的速度較慢,加上比較佔記憶體空間, 因此比較適合用在檔案不太大的XML文件。至於SAX parsing則是 使用event handling的形式,parser會在讀取文件的同時,對每一個element 觸發startElement、endElement等事件,並且由對應的event handler來做 處理。這樣的好處是速度快,因為不需要在記憶體裡面建立長期性的資料 結構,但是一來若要查詢第二次必須重新parse,二來要搜尋某一個 特殊的tag或其他資料的話會比較困難。 首先,我們來看看一個DOM parsing的例子,實際上DOM parsing 是比較容易操作的,因為DOM採用tree的資料結構來將許多問題包裝起來。 要使用DOM parsing,我們必須先建立一個DocumentBuilder,也就是 一般稱呼的parser: -------------------------------------------------------------------------------------------------- DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance(); DocumentBuilder db=dbf.newDocumentBuilder(); -------------------------------------------------------------------------------------------------- 為什麼我們要透過DocumentBuilderFactory而不是直接new一個DocumentBuilder呢? 這是因為JAXP希望把API和實作的引擎切開,當我們呼叫DocumentBuilderFactory.newInstance() 這個函式的時候,實際上會去產生一個由底層引擎所實作的DocumentBuilderFactory, 因為在API裡面的DocumentBuilderFactory是一個抽象的類別,只是提供一個介面而已。 底層引擎所產生的這個DocumentBuilderFactory在呼叫newDocumentBuilder()的時候, 當然會去產生底層引擎所實作的那個DocumentBuilder,但是這一切對使用JAXP API 的programmer來說都是不可見的,因為我們看到的,只是DocumentBuilder這一個 抽象類別。 接著我們要來parse一個xml檔案 -------------------------------------------------------------------------------------------------- Document doc=db.parse(new java.io.File("test.xml")); -------------------------------------------------------------------------------------------------- 當我們呼叫parse這個函式的時候,底層引擎所實作的那個parser就會把test.xml 這個檔案讀進來,產生一個DOM tree,並且傳回一個代表整份文件的Document, 注意這個Document並不代表文件中一個可見的node,但是之後對這份文件的操作 都從Document開始。 我們可以對建立好的DOM tree做查詢的操作 -------------------------------------------------------------------------------------------------- NodeList list=doc.getElementsByTagName("tag_student"); int length=list.getLength(); for(int i=0;i