用JAXB生成一個XML文檔

版權聲明:可以任意轉載,轉載時請務必以超鏈接形式標明文章原始出處和作者信息及本聲明
作者:
Deepak Vohra;simmone
原文地址:http://www.onjava.com/pub/a/onjava/2004/12/15/jaxb.html
中文地址:http://www.matrix.org.cn/resource/article/43/43889_JAXB.html
關鍵詞: JAXB XML

一個XML 模式(Schema)用XML語法表達了一個XML文檔的結構。J2EE的開發者也許會需要一個符合XML模式的XML文檔。Java XML綁定架構(JAXB)提供了一個綁定編譯器,xjc,來從一個XML模式中生成Java類。用JAXB的xjc生成的Java類代表了在XML模式中不同的元素和複雜類型(complexType)。(一個複雜類型通過指定屬性和元素內的元素來提供對一個元素的限定)。一個符合XML模式的XML文檔可以從這些Java類中構建出來。

在這篇教程中,作者使用了JAXB用來從一個XML模式中生成Java類。這些Java類將會生成一個範例XML文檔。這篇文章由以下幾個部份組成:

1.預設置
2.概述
3.從XMl模式中生成Java類
4.從Java類中生成一個XML文檔

預設置
爲了用JAXB從一個XML模式中生成Java類,JAXB API類庫和xjc工具應該存在CLASSPATH環境變量中。將Java Web服務開發包 (JWSDP) 1.5裝入一個安裝目錄中。將下列的.jar文件加入CLASSPATH環境變量中。
·<JWSDP>/jaxb/lib/jaxb-api.jar
·<JWSDP>/jaxb/lib/jaxb-impl.jar
·<JWSDP>/jaxb/lib/jaxb-libs.jar
·<JWSDP>/jaxb/lib/jaxb-xjc.jar
·<JWSDP>/jwsdp-shared/lib/namespace.jar
·<JWSDP>/jwsdp-shared/lib/jax-qname.jar
·<JWSDP>/jwsdp-shared/lib/relaxngDatatype.jar

<JWSDP>是Java Web服務開發包1.5的安裝目錄。把<JWSDP>/jaxb/bin加入PATH環境變量中。<JWSDP>/jaxb/bin目錄中包含了xjc編譯器。把<JWSDP>/jwsdp-shared/bin目錄加入到PATH環境變量中。<JWSDP>/jwsdp-shared/bin目錄中包含了setenv的批處理文件,它設置了JAVA_HOME, ANT_HOME和JWSDP_HOME這幾個環境變量。

概述
JAXB生成對應着XML頂層元素和頂層複雜類型元素 的Java類和接口。在一個XML模式中,一個元素由<xs:element/>表示,一個複雜類型元素由<xs:complexType/>表示。這篇教程列舉了一個能夠表示一篇在科學雜誌上發表的文章的示例模式,同時這個示例模式將會被JAXB綁定編譯器編譯。XML模式,catalog.xsd,如下:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="catalog" type="catalogType"/>
<xsd:complexType name="catalogType">
  <xsd:sequence>
   <xsd:element ref="journal"  minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
  <xsd:attribute name="section" type="xsd:string"/>
  <xsd:attribute name="publisher" type="xsd:string"/>
</xsd:complexType>
<xsd:element name="journal" type="journalType"/>
<xsd:complexType name="journalType">
  <xsd:sequence>
   <xsd:element ref="article"  minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>
<xsd:element name="article" type="articleType"/>
<xsd:complexType name="articleType">
  <xsd:sequence>
   <xsd:element name="title" type="xsd:string"/>
   <xsd:element name="author" type="xsd:string"/>
  </xsd:sequence>
  <xsd:attribute name="level" type="xsd:string"/>
  <xsd:attribute name="date" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>


一些XML模式的構造不被JAXB支持。如果這些不被支持的構造包含在了模式中,那麼當你試圖用xjc來生成Java類時將會報錯。下列模式元素不被支持:xs:any, xs:anyAttribute, xs:notation, xs:redefine, xs:key, xs:keyref, 和 xs:unique. 下列模式的屬性不被支持: complexType.abstract, element.abstract, element.substitutionGroup, xsi:type, complexType.block, complexType.final, element.block, element.final, schema.blockDefault, 和 schema.finalDefault.

生成Java類
xjc工具基於此模式來綁定一個模式到Java類。針對本文的示例模式來進行綁定的命令是:
>xjc catalog.xsd

xjc命令行接口的一些選項列在下表:
-nv        對於輸入的模式不執行嚴格的XML驗證
-b <file>        指定外部的綁定文件
-d <dir>        指定生成的文件的存放路徑
-p <pkg>        指定目標包
-classpath <arg>         指定classpath
-use-runtime <pkg>        impl.runtime包不被生成
-xmlschema        輸入的模式是一個W3C XML模式(默認)

對於示例模式catalog.xsd來說,xjc將會生成45個類,顯示在如下xjc的輸出中:
parsing a schema...
compiling a schema...
generated/impl/runtime/ErrorHandlerAdaptor.java
generated/impl/runtime/MSVValidator.java
generated/impl/runtime/NamespaceContext2.java
generated/impl/runtime/UnmarshallableObject.java
generated/impl/runtime/MarshallerImpl.java
generated/impl/runtime/ValidationContext.java
generated/impl/runtime/UnmarshallerImpl.java
generated/impl/runtime/DefaultJAXBContextImpl.java
generated/impl/runtime/ContentHandlerAdaptor.java
generated/impl/runtime/GrammarInfoFacade.java
generated/impl/runtime/UnmarshallingContext.java
generated/impl/runtime/UnmarshallingEventHandlerAdaptor.java
generated/impl/runtime/XMLSerializable.java
generated/impl/runtime/Discarder.java
generated/impl/runtime/PrefixCallback.java
generated/impl/runtime/SAXMarshaller.java
generated/impl/runtime/NamespaceContextImpl.java
generated/impl/runtime/UnmarshallingEventHandler.java
generated/impl/runtime/GrammarInfo.java
generated/impl/runtime/InterningUnmarshallerHandler.java
generated/impl/runtime/ValidatableObject.java
generated/impl/runtime/GrammarInfoImpl.java
generated/impl/runtime/ValidatingUnmarshaller.java
generated/impl/runtime/ValidatorImpl.java
generated/impl/runtime/SAXUnmarshallerHandlerImpl.java
generated/impl/runtime/XMLSerializer.java
generated/impl/runtime/Util.java
generated/impl/runtime/SAXUnmarshallerHandler.java
generated/impl/runtime/AbstractUnmarshallingEventHandlerImpl.java
generated/impl/ArticleImpl.java
generated/impl/ArticleTypeImpl.java
generated/impl/CatalogImpl.java
generated/impl/CatalogTypeImpl.java
generated/impl/JAXBVersion.java
generated/impl/JournalImpl.java
generated/impl/JournalTypeImpl.java
generated/Article.java
generated/ArticleType.java
generated/Catalog.java
generated/CatalogType.java
generated/Journal.java
generated/JournalType.java
generated/ObjectFactory.java
generated/bgm.ser
generated/jaxb.properties


對於示例XML模式中的每個頂層xs:element和頂層xs:complexType,都對應地生成了一個Java接口和一個Java類。同時也創建了一個工廠類(ObjectFactory.java),包含了創建接口對象的方法。可以在在篇文章的示例代碼文件jaxb-java-resources.zip中找到ObjectFactory.java類。
Catalog.java是對應頂層元素catalog生成的接口。從模式的元素中生成的接口擴展了javax.xml.bin.Elemnt類。

Catalog.java:
package generated;
public interface Catalog
  extends javax.xml.bind.Element, generated.CatalogType
{
}


CatalogType.java是對應頂層複雜元素catalogType生成的接口。CatalogType接口對應catalog元素的每個屬性指定了setter和getter方法,還有對應catalog元素中的journal元素 的一個getter方法。

CatalogType.java:

package generated;
public interface CatalogType {
    java.lang.String getSection();
    void setSection(java.lang.String value);
    java.util.List getJournal();
    java.lang.String getPublisher();
    void setPublisher(java.lang.String value);
}

  
CatalogImpl.java 和CatalogTypeImpl.java是分別對應Catalog.java 和 CatalogType.java接口的實現類。

從Java類中創建一個XML文檔
這一節中,一個示例XMl文檔將會通進JAXB從Java類被創建。示例XML文檔,catalog.xml,如下顯示:
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.w3.org/2001/XMLSchema-Instance"
        section="Java Technology"
        publisher="IBM  developerWorks">
    <journal>          
       <article level="Intermediate"  date="January-2004" >
          <title>Service Oriented Architecture Frameworks </title>
           <author>Naveen Balani</author>
       </article>
      <article level="Advanced" date="October-2003"  >
          <title>Advance DAO Programming</title>
          <author>Sean Sullivan</author>
       </article>
       <article level="Advanced" date="May-2002"  >
          <title>Best Practices in EJB Exception Handling  </title>
          <author>Srikanth Shenoy    </author>
       </article>
   </journal>
</catalog>


從Java類中創建一個CatalogImpl類, 並且使用一個Marshaller(排列者)將CatalogImpl序列化來生成一個XML文檔。

創建Marshaller(排列者)
首先,導入javax.xml.bind包,其中包含了Marshaller, UnMarshaller, 和 JAXBContext類。Marshaller類用來將一個Java類轉換爲XML數據。UnMarshaller類轉換一個XML文檔成Java對象。
import javax.xml.bind.*;


創建一個JAXBContext
一個JAXBContext對象被用來實現JAXB綁定框架的操作:marshal, unmarshal和validate。應用使用靜態方法newInstance(String contextPath)來創建一個新實例(對象)。contextPath指明一組由模式生成的接口的包名。
JAXBContext jaxbContext=JAXBContext.newInstance("generated");


目錄generated包含了JAXB生成的類和接口
使用createMarshaller方法創建一個Marshaller。Marshaller類重載了marshal方法,可以將Java對象序列化(也就是,轉換一個Java對象到XML數據)成SAX2事件,文檔對象模型(DOM),OutputStream, javax.xml.transform.Result或者java.io.Writer對象。

Marshaller marshaller=jaxbContext.createMarshaller();


爲XML文檔創建一個Java對象:CatalogImpl
爲了創建一個Java對象,首選生成一個ObjectFactory。ObjectFactory將會創建一個實現類的實例。對於每一個模式生成的Java類,ObjectFactory中定義了一個靜態方法來創建一個它的對象。
ObjectFactory factory=new ObjectFactory();


使用ObjectFactory類中的createCatalog來創建一個catalog元素。CatalogImpl是Catalog接口的實現類。
CatalogImpl catalog=(CatalogImpl)(factory.createCatalog());
使用CatalogImpl類中的setSection方法來設置catalog元素的section屬性。
catalog.setSection("Java Technology");

用setPublisher方法來設置catalog元素的publisher屬性。
catalog.setPublisher("IBM developerWorks");


爲XML文檔創建一個Java對象:JournalImpl和ArticleImpl
用ObjectFactory類中的createJournal方法來創建一個jounal元素。JournalImpl是Journal接口的實現類。
JournalImpl journal=(JournalImpl)(factory.createJournal());

將journal元素加入catalog元素。從CatalogImpl得到JournalImpl的java.util.List,並把journal元素加入到List中。
java.util.List journalList=catalog.getJournal();
journalList.add(journal);


使用ObjectFactory類的createArticle方法來創建journal中的article元素。ArticleImpl是Article接口的實現類。
ArticleImpl article=(ArticleImpl)(factory.createArticle());


使用ArticleImpl類中的setLevel方法來設置article元素的level屬性。
article.setLevel("Intermediate");

用setDate方法設置article的date屬性
article.setDate("January-2004");


用setTitle方法創建article元素的title屬性
article.setTitle("Service Oriented Architecture Frameworks");


用setAuthor方法創建article元素的author屬性
article.setAuthor("Naveen Balani");


將article元素加入journal元素中。從JournalImpl中得到ArticleImpl的java.util.List,並將article元素加入List中。
java.util.List  articleList=journal.getArticle();
articleList.add(article);


與創建article元素的過程相類似,其它article元素也將被創建用來生成示例XML文檔catalog.xml
將Java對象序列化爲一個XML文檔
用Marshaller類中的marshal方法來將CatalogImpl對象序列化爲一個XML文檔。CatalogImpl對象被序列化爲一個OutputStream
marshaller.marshal(catalog, new FileOutputStream(xmlDocument));


xmlDocument是輸出的XML的java.io.File對象,它代表的是本節一開始所展示的XML文檔。JAXBConstructor.java,這個程序用來從Java類中生成一個XML文檔,也在這篇文章的示例代碼文件中。

總結
JAXB提供了一個綁定編譯器xjc, 從一個模式中生成Java對象,然後這些Java對象可以序列化爲一個XML文檔。但是,JAXB有一個限制:它不支持所有的XML模式結構。

資源
·" Java XML 綁定架構"
·"XML 模式結構"
·Java Web 服務開發包 1.5
·這篇文章的示例代碼: jaxb-java-resources.zip:[下載文件]

Deepak Vohra 是一個NuBean的顧問和一個web開發者.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章