<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    使用JAXB處理XML文檔――先睹為快

    JAXB以其方便的XML數據處理能力可能會引起你的興趣。你可能還不了解JAXB是什么,想要知道它到底有什么好處,如果這是你需要的,你才會再花時間去細細的研究它,或者你只需要使用最基本的功能。然而Sun關于JAXB的文檔有80頁之多。我想大部分人都沒有耐心看完這樣的長篇大論。本文以簡短的篇幅介紹了JAXB的基本使用,算是先睹為快吧。本文附帶的代碼包括了JAXB1.0 early access版本和本文所使用的代碼。歡迎與我討論: mailto:boyofjava@sina.com

     

    本文假設你會使用Java編程,了解并能夠看懂XMLDTD

     

    1 為什么要使用JAXB

    Java中處理XML數據的常規方法有SAXDOM等。其中SAX使用起來很麻煩,不能修改XML數據;而DOM的處理大文檔速度非常的慢,易用性也不必SAX好到哪里去。實際上,無論是SAX還是DOM都不是專門為Java準備的,它們都是訪問XML文檔的統一底層接口,與語言無關。

    現在我們有了另外的選擇。這就是JAXBJDOMJDOM與本文無關,目前最新的版本是beta8,感興趣的話,可以訪問http://www.jdom.org/

    JAXB的全名是Java ? Architecture for XML Binding,目前是1.0early access版本,在SunJava站點只有注冊為成員才能夠下載。JAXB的特點就是將你用DTD定義好的XML文檔映射為Java對象,提供簡單、快速的數據操作方式。要訪問XML中的元素、屬性只要通過相應對象上的一系列getter setter方法。你還可以通過marshal方法將對象的數據寫進XML文件,通過unmarshal方法將XML文件的數據讀入對象,通過validate方法驗證XML文件是否符合DTD的約束。JAXB的缺點就在于只能訪問特定的(也就是你用DTD定義的)XML文檔。

     

    2 JAXB如何工作

    JAXB包括了一個運行類庫和一個模式編譯器。首先你要定義XMLDTD,然后編寫一個綁定模式(Binding Schema)。DTD定義了XML文檔,綁定模式也是一個XML文件,指出DTD定義的XML文檔如何被映射為Java對象。運行編譯器,將DTD和綁定模式作為參數傳給編譯器,編譯器就會生成Java代碼。編譯生成的Java代碼,通過這些代碼就可以訪問XML文檔了。

     

    3 JAXB的安裝

    1.0 early access為例,它不包含在JDK中,先到http://java.sun.com/xml下載。注意由于是早期版本,需要先登錄才能下載,本文附帶的源碼包含了JAXB1.0 early access。下載后將文件解壓縮,在lib目錄中有兩個文件。jaxb-rt-1.0-ea.jar是運行支持庫,jaxb-xjc-1.0-ea.jar是模式編譯器。注意bin目錄中的xjc文件只能在UNIX下使用,如果你的系統是Windows,那么你需要在命令行窗口手工輸入命令來編譯。為了在任何地方都可以運行模式編譯器和它生成的代碼,我們要把這兩的文件加入CLASSPATH。一個簡單的辦法是把這兩個文件拷貝到jre/lib/ext下。

     

    4 一個簡單的例子

    有這樣一個XML文檔。它描述書的列表,舉例如下:

    文件exampleA.xml

    <?xml version="1.0" encoding="GBK"?>

    <bookList>

        <book>

            <name>Java編程入門</name>

            <author>張三</author>

            <publishDate>2002-6-6</publishDate>

            <price>35.0</price>

        </book>

        <book>

            <name>XMLJava中的應用</name>

            <author>李四</author>

            <publishDate>2002-9-16</publishDate>

            <price>92.0</price>

        </book>

    </bookList>

     

    DTD文件如下:

    文件bookList.dtd

    <!ELEMENT bookList (book)*>

    <!ELEMENT book(name,author,publishDate,price)>

    <!ELEMENT name (#PCDATA)>

    <!ELEMENT author (#PCDATA)>

    <!ELEMENT publishDate (#PCDATA)>

    <!ELEMENT price (#PCDATA)>

     

    現在我們就來編寫一個最簡單的綁定模式,其文件擴展名應該為xjs

    文件bookList.xjs

    <xml-java-binding-schema version="1.0-ea">

        <element name="bookList" type="class" root="true"/>

    </xml-java-binding-schema>

     

    現在就可以運行模式編譯器生成Java代碼,請先保證CLASSPATH中包含了JAXB的兩個JAR文件。Windows用戶注意bin目錄下的那個文件是沒用的。在命令行運行:

    java com.sun.tools.xjc.Main bookList.dtd bookList.xjs

    如果沒出問題,編譯器就生成了Book.javaBookList.java兩個文件。你不用去理解這兩個源文件里面的代碼,只要知道怎么使用它們提供的方法就可以了。它們的繼承結構都是這樣的:

    java.lang.Object

       javax.xml.bind.ValidatableObject

          javax.xml.bind.MarshallableObject

             javax.xml.bind.MarshallableRootElement

                    BookList or Book

     

    BookList.java主要包含了以下方法

    BookList()    //構造函數

    List getBook()    //得到書的集合,List中的對象實際類型是Book,可以添加、修改、刪除其中的元素

    void deleteBook()   //刪除集合

    void emptyBook()    //刪除并生成一個新的空集合

    void marshal(X)      //將數據寫進XML文檔

    void unmarshal(X)   //將數據從XML文檔讀入對象

    void validate(X)    //檢查是否符合DTD約束,同時檢查子樹。在這個例子中就是BookListBook集合

    void validateThis()   //檢查是否符合DTD約束,不檢查子樹

    其中marshalunmarshalvalidate被重載,有多種參數形式(可以參考JAXBAPI文檔)。

     

     

    Book.java主要包含了以下方法

    Book()

    String getName()

    String getAuthor()

    String getPublishDate()

    String getPrice()

    void setName(String x)

    void setAuthor(String x)

    void setPublishDate(String x)

    void setPrice(String x)

    void marshal()

    void unmarshal()

    void validate()

     

    現在我們就可以使用這兩個文件訪問XML了。首先編譯這兩個文件。編寫一個Test.java文件,把它和生成的兩個文件以及前面的exampleA.xml放在一起。這個程序從 exampleA.xml讀入數據,作修改(把第一本書作者改成王五)后寫入exampleB.xml。因為中文的編碼問題,所以我們需要多一點手續。

    文件Test.java

    import java.io.*;

    import java.util.*;

    import javax.xml.bind.*;

    import javax.xml.marshal.*;

    public class Test{

           public static void main(String[] args) throws Exception{

            BookList bl = new BookList();

            FileInputStream fis = new FileInputStream("exampleA.xml");

            try{

                bl = bl.unmarshal(fis);

            }finally{

                fis.close();

            }

            List books = bl.getBook();

            Book b = (Book)books.get(0);

            b.setAuthor("王五");

     

            bl.validate();  //先驗證,不然marshal會出錯

            FileOutputStream fos = new FileOutputStream("exampleB.xml");

            XMLWriter xw = new XMLWriter(fos,"GBK");

            try{

                bl.marshal(xw);

            }finally{

                fos.close();

            }

           }

    }

     

    編譯運行,生成的文件exampleB.xml如下:

    <?xml version="1.0" encoding="GBK"?>

     

    <bookList>

      <book>

        <name>Java編程入門</name>

        <author>王五</author>

        <publishDate>2002-6-6</publishDate>

        <price>35.0</price></book>

      <book>

        <name>XMLJava中的應用</name>

        <author>李四</author>

        <publishDate>2002-9-16</publishDate>

    <price>92.0</price></book></bookList>

     

    5 更進一步:數據類型轉換

    你可能已經注意到在上面的例子中,生成的Book對象的getPrice方法返回的是String,實際上它應該是float。同樣publishDate以該是日期類型,而不是字符串。這是因為我們的綁定模式寫得太簡單了,模式編譯器生成了默認的String類型。現在我們這樣寫:

    文件bookList2.xjs

    <xml-java-binding-schema version="1.0-ea">

        <element name="bookList" type="class" root="true"/>

        <element name="price" type="value" convert="float"/>

        <element name="publishDate" type="value" convert="TransDate" />

        <conversion name="TransDate" type="java.util.Date"

                parse="TransDate.parseDate" print="TransDate.printDate"/>

    </xml-java-binding-schema>

     

    java com.sun.tools.xjc.Main bookList.dtd bookList2.xjs運行編譯器。生成的Book文件的相應代碼為:

    float getPrice()

    java.util.Date getPublishDate()

     

    bookList2.xjs3行將Price轉換成了float類型,float類型是一個簡單類型,因此用convert="float"描述就可以了。而 publishDate需要轉變成java.util.Date,這是一個類,而且他沒有以字符串作為參數的構造函數。parse="TransDate.parseDate"就表示使用unmarshal讀取數據的時候,會調用TransDate.parseDate()方法。這個靜態方法以字符串為參數,返回java.util.dateprint="TransDate.printDate"的作用相反。TransDate這個類需要我們提供。

    文件TransDate.java

    import java.util.Date;

    public class TransDate {

        private static java.text.SimpleDateFormat df

               = new java.text.SimpleDateFormat("yyyy-MM-dd");

     

        public static Date parseDate(String d) {

               try {

                   return df.parse(d);

              } catch (java.text.ParseException pe) {

                   System.out.print(pe);

                   return new Date();

               }

        }

     

        public static String printDate(Date d) {

               return df.format(d);

        }

    }

     

    6 那些使JAXB能夠做到,但本文沒有提到的

    本文提供的這個例子很簡單,實際上JAXB還可以定義文檔的哪些元素(屬性)可以被轉換成類,哪些被轉換成類的屬性。處理元素的屬性。處理枚舉值。為一些元素共同的子元素生成接口(因為JAXB不支持NameSpace),定義繼承結構等等。

     

    7 JAXB不能做到的

    Sun的文檔里提到的:

    僅支持用DTD定義XML

    不支持NameSpace

    不支持內部子集、NOTATIONsENTITYENTITIES等。

     

    另外,我發現如果要寫一條處理指令到XML文檔中,例如指定轉換的樣式單

    <?xml-stylesheet href=”a.xsl” type=”text/xsl”?>

    JAXB中好像做不到,在javax.xml.marshal.XMLWriter中有一個chars(String str)方法,可以把字符串到XML文件的聲明后面,但是這個方法對特殊字符作了轉義,也就是沒辦法可以做到。這很奇怪,因為這是一個常用的功能,要實現也不難。也許還有我沒有發現的辦法。倒是有一個doctype方法可以寫DOCTYPE聲明。

     

    8 參考文檔

    1 The Java ? Architecture for XML Binding User’s Guide

     (http://java.sun.com/xml/jaxb/jaxb-docs.pdf)

    2 Web Services Made Easier. The Java TM APIs and Architectures for XML, A Technical White Paper (http://java.sun.com/xml/webservices.pdf )

    轉自:http://www.csdn.com.cn/program/2823.htm

    posted on 2005-04-23 14:34 weidagang2046 閱讀(596) 評論(0)  編輯  收藏 所屬分類: XML

    主站蜘蛛池模板: 亚洲人成网站在线播放2019| 日韩特黄特色大片免费视频| 在线精品一卡乱码免费| 成年性生交大片免费看| 亚洲AV成人潮喷综合网| 国产亚洲精品a在线观看app | 日韩吃奶摸下AA片免费观看| 麻豆国产精品入口免费观看| 69天堂人成无码麻豆免费视频| 女人张开腿等男人桶免费视频| 亚洲AⅤ无码一区二区三区在线| 亚洲AV无码一区二区乱孑伦AS| 91午夜精品亚洲一区二区三区| 国产精品久久久久久亚洲小说| a级成人毛片免费视频高清| 亚洲天堂免费在线| 亚洲成aⅴ人片久青草影院| 亚洲2022国产成人精品无码区| 国产亚洲福利在线视频| 成在线人免费无码高潮喷水| 91频在线观看免费大全| 亚洲麻豆精品国偷自产在线91| 久久久久亚洲AV无码永不| 亚洲国产成人私人影院| 中文字幕无码亚洲欧洲日韩| 亚洲一级片免费看| 国产一卡2卡3卡4卡无卡免费视频| 一本色道久久88亚洲综合 | 久久亚洲AV成人无码国产电影| 国产一级a毛一级a看免费视频 | 亚洲成AV人片在| 亚洲精品宾馆在线精品酒店| 成人A片产无码免费视频在线观看 成人电影在线免费观看 | 久久亚洲国产成人影院| 东北美女野外bbwbbw免费| 成年人免费观看视频网站| 亚洲av综合色区| 边摸边吃奶边做爽免费视频网站 | 亚洲激情中文字幕| 国产亚洲精品免费| 18禁美女裸体免费网站|