JAXB以其方便的XML數(shù)據(jù)處理能力可能會引起你的興趣。你可能還不了解JAXB是什么,想要知道它到底有什么好處,如果這是你需要的,你才會再花時間去細細的研究它,或者你只需要使用最基本的功能。然而Sun關(guān)于JAXB的文檔有80頁之多。我想大部分人都沒有耐心看完這樣的長篇大論。本文以簡短的篇幅介紹了JAXB的基本使用,算是先睹為快吧。本文附帶的代碼包括了JAXB1.0 early access版本和本文所使用的代碼。歡迎與我討論: boyofjava@sina.com
本文假設(shè)你會使用Java編程,了解并能夠看懂XML,DTD。 1 為什么要使用JAXB 在Java中處理XML數(shù)據(jù)的常規(guī)方法有SAX,DOM等。其中SAX使用起來很麻煩,不能修改XML數(shù)據(jù);而DOM的處理大文檔速度非常的慢,易用性也不必SAX好到哪里去。實際上,無論是SAX還是DOM都不是專門為Java準備的,它們都是訪問XML文檔的統(tǒng)一底層接口,與語言無關(guān)。 現(xiàn)在我們有了另外的選擇。這就是JAXB和JDOM。JDOM與本文無關(guān),目前最新的版本是beta8,感興趣的話,可以訪問http://www./。JAXB的全名是Java ™ Architecture for XML Binding,目前是1.0的early access版本,在Sun的Java站點只有注冊為成員才能夠下載。JAXB的特點就是將你用DTD定義好的XML文檔映射為Java對象,提供簡單、快速的數(shù)據(jù)操作方式。要訪問XML中的元素、屬性只要通過相應(yīng)對象上的一系列g(shù)etter和 setter方法。你還可以通過marshal方法將對象的數(shù)據(jù)寫進XML文件,通過unmarshal方法將XML文件的數(shù)據(jù)讀入對象,通過validate方法驗證XML文件是否符合DTD的約束。JAXB的缺點就在于只能訪問特定的(也就是你用DTD定義的)XML文檔。 2 JAXB如何工作 JAXB包括了一個運行類庫和一個模式編譯器。首先你要定義XML的DTD,然后編寫一個綁定模式(Binding Schema)。DTD定義了XML文檔,綁定模式也是一個XML文件,指出DTD定義的XML文檔如何被映射為Java對象。運行編譯器,將DTD和綁定模式作為參數(shù)傳給編譯器,編譯器就會生成Java代碼。編譯生成的Java代碼,通過這些代碼就可以訪問XML文檔了。 3 JAXB的安裝 以1.0 early access為例,它不包含在JDK中,先到http://java./xml下載。注意由于是早期版本,需要先登錄才能下載,本文附帶的源碼包含了JAXB1.0 early access。下載后將文件解壓縮,在lib目錄中有兩個文件。jaxb-rt-1.0-ea.jar是運行支持庫,jaxb-xjc-1.0-ea.jar是模式編譯器。注意bin目錄中的xjc文件只能在UNIX下使用,如果你的系統(tǒng)是Windows,那么你需要在命令行窗口手工輸入命令來編譯。為了在任何地方都可以運行模式編譯器和它生成的代碼,我們要把這兩的文件加入CLASSPATH。一個簡單的辦法是把這兩個文件拷貝到j(luò)re/lib/ext下。 4 一個簡單的例子 有這樣一個XML文檔。它描述書的列表,舉例如下: quote: 其DTD文件如下: quote: 現(xiàn)在我們就來編寫一個最簡單的綁定模式,其文件擴展名應(yīng)該為xjs。文件bookList.xjs quote: 現(xiàn)在就可以運行模式編譯器生成Java代碼,請先保證CLASSPATH中包含了JAXB的兩個JAR文件。Windows用戶注意bin目錄下的那個文件是沒用的。在命令行運行: java com.sun.tools.xjc.Main bookList.dtd bookList.xjs
如果沒出問題,編譯器就生成了Book.java,BookList.java兩個文件。你不用去理解這兩個源文件里面的代碼,只要知道怎么使用它們提供的方法就可以了。它們的繼承結(jié)構(gòu)都是這樣的: java.lang.Object javax.xml.bind.ValidatableObject javax.xml.bind.MarshallableObject javax.xml.bind.MarshallableRootElement BookList or Book BookList.java主要包含了以下方法 quote: 現(xiàn)在我們就可以使用這兩個文件訪問XML了。首先編譯這兩個文件。編寫一個Test.java文件,把它和生成的兩個文件以及前面的exampleA.xml放在一起。這個程序從 exampleA.xml讀入數(shù)據(jù),作修改(把第一本書作者改成王五)后寫入exampleB.xml。因為中文的編碼問題,所以我們需要多一點手續(xù)。 quote: 編譯運行,生成的文件exampleB.xml如下: quote: 5 更進一步:數(shù)據(jù)類型轉(zhuǎn)換 你可能已經(jīng)注意到在上面的例子中,生成的Book對象的getPrice方法返回的是String,實際上它應(yīng)該是float。同樣publishDate以該是日期類型,而不是字符串。這是因為我們的綁定模式寫得太簡單了,模式編譯器生成了默認的String類型?,F(xiàn)在我們這樣寫: quote: 用java com.sun.tools.xjc.Main bookList.dtd bookList2.xjs運行編譯器。生成的Book文件的相應(yīng)代碼為: float getPrice() java.util.Date getPublishDate() bookList2.xjs第3行將Price轉(zhuǎn)換成了float類型,float類型是一個簡單類型,因此用convert="float"描述就可以了。而 publishDate需要轉(zhuǎn)變成 java.util.Date,這是一個類,而且他沒有以字符串作為參數(shù)的構(gòu)造函數(shù)。parse="TransDate.parseDate"就表示使用unmarshal讀取數(shù)據(jù)的時候,會調(diào)用TransDate.parseDate()方法。這個靜態(tài)方法以字符串為參數(shù),返回java.util.date。print="TransDate.printDate"的作用相反。TransDate這個類需要我們提供。 quote: 6 那些使JAXB能夠做到,但本文沒有提到的 本文提供的這個例子很簡單,實際上JAXB還可以定義文檔的哪些元素(屬性)可以被轉(zhuǎn)換成類,哪些被轉(zhuǎn)換成類的屬性。處理元素的屬性。處理枚舉值。為一些元素共同的子元素生成接口(因為JAXB不支持NameSpace),定義繼承結(jié)構(gòu)等等。 7 JAXB不能做到的 Sun的文檔里提到的:僅支持用DTD定義XML不支持NameSpace不支持內(nèi)部子集、NOTATIONs、ENTITY、ENTITIES等。 另外,我發(fā)現(xiàn)如果要寫一條處理指令到XML文檔中,例如指定轉(zhuǎn)換的樣式單 <?xml-stylesheet href=”a.xsl” type=”text/xsl”?> 在JAXB中好像做不到,在javax.xml.marshal.XMLWriter中有一個chars(String str)方法,可以把字符串到XML文件的聲明后面,但是這個方法對特殊字符作了轉(zhuǎn)義,也就是沒辦法可以做到。這很奇怪,因為這是一個常用的功能,要實現(xiàn)也不難。也許還有我沒有發(fā)現(xiàn)的辦法。倒是有一個doctype方法可以寫DOCTYPE聲明。 8 參考文檔 1 The Java ™ Architecture for XML Binding User’s Guide (http://java./xml/jaxb/jaxb-docs.pdf) 2 Web Services Made Easier. The Java TM APIs and Architectures for XML, A Technical White Paper (http://java./xml/webservices.pdf ) |
|