日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

使用JAXB将XML Schema绑定到Java类

發(fā)布時(shí)間:2024/4/17 55 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用JAXB将XML Schema绑定到Java类 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://blog.csdn.net/zsyspace/article/details/1786079

Java Architecture for XML Binding (JAXB) 是一項(xiàng)可以根據(jù)XML 模式產(chǎn)生Java類的Java技術(shù)。該過程中,JAXB也提供了將XML實(shí)例文檔反編組到Java內(nèi)容樹的方法,并能將Java內(nèi)容樹編組回XML實(shí)例文檔。從另一方面來講,JAXB提供了快速而簡(jiǎn)便的方法將XML模式綁定到Java表示,從而使得Java開發(fā)者在Java應(yīng)用程序中能方便地結(jié)合XML數(shù)據(jù)和處理函數(shù)。

這意味著你不需要處理甚至不需要知道XML編程技巧就能在Java應(yīng)用程序中利用平臺(tái)核心XML數(shù)據(jù)的靈活性。而且,可以充分利用XML的優(yōu)勢(shì)而不用依賴于復(fù)雜的XML處理模型如SAX或DOM。JAXB 隱藏了細(xì)節(jié)并且取消了SAX和DOM中沒用的關(guān)系——生成的JAXB類僅描述原始模型中定義的關(guān)系。其結(jié)果是結(jié)合了高度可移植Java代碼的高度可移植的XML數(shù)據(jù),其中這些代碼可用來創(chuàng)建靈活、輕便的應(yīng)用程序和Web服務(wù)。

本章介紹了JAXB體系結(jié)構(gòu)、函數(shù)和核心概念。在學(xué)習(xí)第十章之前必須先閱讀本章。第十章給出了示例代碼和逐步使用JAXB的過程。

JAXB 體系結(jié)構(gòu)

本節(jié)主要討論JAXB處理模型中的組件和交互。在給出了總的概述之后,本節(jié)將詳細(xì)討論核心的JAXB特性。本節(jié)中的主題主要包括:

  • 體系結(jié)構(gòu)概述
  • JAXB綁定過程
  • JAXB 綁定框架
  • 關(guān)于javax.xml.bind的更多信息
  • 關(guān)于反編組的更多信息
  • 關(guān)于編組的更多信息
  • 關(guān)于驗(yàn)證的更多信息

體系結(jié)構(gòu)概述

圖 9-1 給出了構(gòu)成JAXB實(shí)現(xiàn)的組件。

圖 9-1 JAXB體系結(jié)構(gòu)概述

如圖9-1所示,JAXB實(shí)現(xiàn)包含下列八個(gè)核心組件:

9-1 JAXB實(shí)現(xiàn)中的核心組件

組件

描述

XML Schema

XML模式使用XML語法描述XML文檔中元素、屬性和實(shí)體之間的關(guān)系。XML模式的目標(biāo)是定義一個(gè)XML文檔類,該類必須堅(jiān)持特定的結(jié)構(gòu)規(guī)則和數(shù)據(jù)約束。例如你可能希望給面向章的書、在線采購系統(tǒng)或個(gè)人數(shù)據(jù)庫定義不同的模式。在JAXB上下文中,將包含數(shù)據(jù)的受到XML模式約束的XML文檔叫做文檔實(shí)例,并且將文檔實(shí)例中的結(jié)構(gòu)和數(shù)據(jù)叫做內(nèi)容樹

Binding
Declarations

默認(rèn)情況下,JAXB綁定編譯器根據(jù)JAXB規(guī)范第5節(jié)“將XML Schema綁定到Java表示”中定義的規(guī)則將Java類和包綁定到原始XML模式。多數(shù)情況下,利用默認(rèn)的規(guī)則已經(jīng)能夠從大量的模式中產(chǎn)生一組強(qiáng)壯的模式派生類。但是,有的時(shí)候,默認(rèn)的綁定規(guī)則就不夠用了。JAXB支持通過綁定聲明自定義或覆蓋默認(rèn)的綁定規(guī)則。這些綁定聲明或者是內(nèi)部源模式的注釋或者是傳遞給JAXB綁定編譯器的外部綁定自定義文件中的語句。注意自定義的JAXB綁定聲明也允許擺脫XML模式中特定于XML的束縛,來自定義生成的JAXB類,以包含特定于Java的改進(jìn),如類和包名映射

Binding
Compiler

JAXB綁定編譯器是JAXB處理模型的核心。它的功能是將源XML模式轉(zhuǎn)換或綁定到Java編程語言中的一組JAXB內(nèi)容類。基本上,可以通過將一個(gè)XML模式 (可以選擇使用自定義綁定聲明)用作輸入來運(yùn)行JAXB綁定編譯器。綁定編譯器產(chǎn)生Java類,這些Java類映射到了源XML 模式中的約束條件

Binding
Framework
Implementation

JAXB綁定框架實(shí)現(xiàn)是運(yùn)行時(shí)API,它提供了反編組、編組和驗(yàn)證Java應(yīng)用程序中的XML內(nèi)容的接口。綁定框架包括javax.xml.bind包中的接口

Schema-Derived
Classes

這些是JAXB編譯器產(chǎn)生的模式派生類。根據(jù)輸入的模式將采用不同的類

Java
Application

JAXB上下文中,Java應(yīng)用程序是客戶端應(yīng)用程序,它使用JAXB綁定框架來反編組XML數(shù)據(jù),驗(yàn)證并修改Java內(nèi)容對(duì)象,并將Java內(nèi)容編組成XML數(shù)據(jù)。特別是,JAXB綁定框架包裝在一個(gè)能提供UI功能、XML轉(zhuǎn)換功能、數(shù)據(jù)處理或其他所需要的功能的大型Java應(yīng)用程序中

XML Input
Documents

這是反編組出來用作JAXB綁定框架輸入的XML內(nèi)容——即XML實(shí)例文檔,從這里將產(chǎn)生內(nèi)容樹形式的Java表示。實(shí)際上,術(shù)語“文檔”不再是傳統(tǒng)意義上的文檔了,因?yàn)?/span>XML實(shí)例文檔不一定要是形式完整的、自立的文檔文件;相反它具有流的形式,這些流可以是應(yīng)用程序之間傳遞的數(shù)據(jù)、數(shù)據(jù)庫字段集合、XML信息集合,其中信息塊包含了描述它們?cè)谀J浇Y(jié)構(gòu)中的位置的足夠信息。

?

JAXB中,反編組過程支持根據(jù)源模式定義的約束驗(yàn)證XML輸入文檔。然而該驗(yàn)證過程是可選的,在某些情況下你可能通過其他途徑知道輸入文檔是有效的,出于對(duì)性能的考慮你可能選擇在反編組過程中跳過驗(yàn)證。但是,無論在哪種情況下,反編組之前(通過第三方應(yīng)用程序)或之后驗(yàn)證都很重要,這是因?yàn)樗_保了關(guān)于源模式編組過程中產(chǎn)生的XML文檔也是有效的。在本章的后面部分將詳細(xì)介紹驗(yàn)證

XML Output
Documents

這是編組到XML文檔的XML內(nèi)容。在JAXB編組包括解析XML內(nèi)容對(duì)象樹并寫出一個(gè)XML文檔,該文檔是原始XML文檔的精確表示并且相對(duì)于原始模式來說是有效的。JAXB能夠?qū)?/span>XML數(shù)據(jù)編組成XML 文檔、SAX內(nèi)容處理程序和DOM節(jié)點(diǎn)。

JAXB綁定過程

圖9-2顯示了JAXB的綁定過程。

圖 9-2 JAXB綁定過程步驟

JAXB數(shù)據(jù)綁定過程的常用步驟是:

1.?????? 生成類。將XML模式放入JAXB綁定編譯器,以產(chǎn)生基于該模式的JAXB類。

2.?????? 編譯類。必須編譯所有生成的類、源文件和應(yīng)用程序代碼。

3.?????? 反編組。JAXB綁定框架反編組根據(jù)原始模式中的約束編寫的XML文檔。注意JAXB也支持反編組來自除了文件/文檔之外XML數(shù)據(jù),如DOM節(jié)點(diǎn)、字符串緩沖、SAX Source等等。

4.?????? 生成內(nèi)容樹。反編組過程產(chǎn)生從生成的JAXB類實(shí)例化而來的數(shù)據(jù)對(duì)象內(nèi)容樹,該內(nèi)容樹代表了源XML文檔的結(jié)構(gòu)和內(nèi)容。

5.?????? 驗(yàn)證(可選)反編組過程中,可以在生成內(nèi)容樹之前驗(yàn)證源XML文檔。注意,如果在第6步中修改內(nèi)容樹,下面,你也能使用JAXB驗(yàn)證操作在將內(nèi)容編組到XML文檔之前驗(yàn)證變化。

6.?????? 處理內(nèi)容。客戶端應(yīng)用程序通過綁定編譯器產(chǎn)生的接口方法可以修改Java內(nèi)容樹表示的XML數(shù)據(jù)。

7.?????? 編組。將處理過的內(nèi)容樹編組到一個(gè)或多個(gè)XML輸出文檔中。在編組之前要驗(yàn)證內(nèi)容。

總而言之,使用JAXB涉及到兩個(gè)獨(dú)立的活動(dòng)集:

  • 根據(jù)源模式生成并編譯JAXB類,并且建立一個(gè)實(shí)現(xiàn)這些類的應(yīng)用程序。
  • 在JAXB綁定框架中運(yùn)行應(yīng)用程序,以反編組、處理、驗(yàn)證和編組XML內(nèi)容。

通常分時(shí)間分階段執(zhí)行這兩個(gè)步驟。典型地,例如,需要在應(yīng)用程序開發(fā)階段生成并編譯JAXB類,并且建立綁定實(shí)現(xiàn),接著是部署階段,在該階段使用生成的JAXB類在“現(xiàn)場(chǎng)”產(chǎn)品環(huán)境中處理XML內(nèi)容。


注意:反編組不是創(chuàng)建內(nèi)容樹的唯一的方法。模式派生的內(nèi)容類通過直接調(diào)用合適的工廠方法也支持按計(jì)劃構(gòu)建內(nèi)容樹。一旦創(chuàng)建了,任何時(shí)候都可以重新驗(yàn)證內(nèi)容樹的一部分或全部。查看示例應(yīng)用程序 3 中的使用ObjectFactory 類直接給內(nèi)容樹添加內(nèi)容的例子。


JAXB綁定框架

JAXB綁定框架由三個(gè)Java包實(shí)現(xiàn):

  • javax.xml.bind 包定義直接和內(nèi)容類一起使用的抽象類和接口。

javax.xml.bind 包定義Unmarshaller、Validator和Marshaller 類,它們是提供各自操作的輔助對(duì)象。

JAXBContext 類是Java應(yīng)用程序到JAXB框架的入口點(diǎn)。JAXBContext 實(shí)例為反編組、編組和驗(yàn)證操作使用的JAXB實(shí)現(xiàn)將XML元素名綁定到Java內(nèi)容接口。

javax.xml.bind 包也定義了編組或反編組錯(cuò)誤出現(xiàn)時(shí)、違反約束時(shí)及出現(xiàn)其他類型的錯(cuò)誤時(shí)使用的豐富的驗(yàn)證事件和異常類的層次結(jié)構(gòu)。

  • javax.xml.bind.util 包包含工具類,客戶端應(yīng)用程序可以使用它們來管理編組、反編組和驗(yàn)證事件。
  • javax.xml.bind.helper 包為一些javax.xml.bind 接口提供了部分默認(rèn)的實(shí)現(xiàn)。JAXB的實(shí)現(xiàn)能夠擴(kuò)展這些類并且實(shí)現(xiàn)抽象方法。使用JAXB體系結(jié)構(gòu)的應(yīng)用程序不能直接使用這些API。

下面將詳細(xì)介紹JAXB綁定框架中的主要的包javax.bind.xml。

關(guān)于javax.xml.bind的更多信息

主要綁定框架包javax.xml.bind提供的三個(gè)核心功能是編組、反編組和驗(yàn)證。到綁定框架的主要的客戶端入口點(diǎn)是JAXBContext 類。

JAXBContext 提供了一個(gè)抽象,該抽象可以管理實(shí)現(xiàn)反編組、編組和驗(yàn)證操作必要的XML/Java綁定信息。客戶端應(yīng)用程序通過newInstance(contextPath)方法得到該類的新實(shí)例。例如:

JAXBContext jc = JAXBContext.newInstance( "com.acme.foo:com.acme.bar" );

contextPath 參數(shù)包含一個(gè)Java包名,這些包包含模式派生的接口—特別是JAXB綁定編譯器產(chǎn)生的接口。該參數(shù)值初始化JAXBContext 對(duì)象,使得它能夠管理模式派生的接口。為此目的,JAXB提供程序?qū)崿F(xiàn)必須提供一個(gè)包含下列特征的實(shí)現(xiàn)類:

public static JAXBContext createContext( String contextPath, ClassLoader classLoader ) ??????throws JAXBException;

注意:在每個(gè)包含模式派生類的包中,JAXB提供程序?qū)崿F(xiàn)必須生成一個(gè)jaxb.properties 文件。該屬性文件必須包含一個(gè)叫做javax.xml.bind.context.factory 的屬性,它的值是實(shí)現(xiàn)createContext API的類的名字。

不一定要將提供程序提供的類分配給javax.xml.bind.JAXBContext,它只是必須提供一個(gè)實(shí)現(xiàn) createContext API的類。允許指定多個(gè)Java包,JAXBContext 實(shí)例允許同時(shí)管理多個(gè)模式。


關(guān)于反編組的更多信息

javax.xml.bind 包中的Unmarshaller 類使得客戶端應(yīng)用程序能夠?qū)ML數(shù)據(jù)轉(zhuǎn)換成Java內(nèi)容對(duì)象樹。模式的unmarshal 方法(在命名空間內(nèi))允許將模式中聲明的任何全局XML元素反編組成實(shí)例文檔的根。JAXBContext 對(duì)象允許在一組模式內(nèi)合并全局元素(列在contextPath中)。由于模式集中的每個(gè)模式屬于不同的命名空間,將模式統(tǒng)一到反編組上下文中是獨(dú)立于命名空間的。這意味著客戶端應(yīng)用程序能夠反編組contextPath 中列出的任何模式的實(shí)例XML文檔。例如:

JAXBContext jc = JAXBContext.newInstance( ??"com.acme.foo:com.acme.bar" ); ? Unmarshaller u = jc.createUnmarshaller(); ? FooObject fooObj = ??(FooObject)u.unmarshal( new File( "foo.xml" ) ); // ok ? BarObject barObj = ??(BarObject)u.unmarshal( new File( "bar.xml" ) ); // ok ? BazObject bazObj = ??(BazObject)u.unmarshal( new File( "baz.xml" ) ); ??// error, "com.acme.baz" not in contextPath

客戶端應(yīng)用程序也能明顯地生成Java內(nèi)容樹而不是反編組現(xiàn)有XML數(shù)據(jù)。這樣做,應(yīng)用程序必須能夠存取并了解contextPath 中的每個(gè)Java包中模式派生的ObjectFactory 類。對(duì)于每個(gè)模式派生Java類,將有一個(gè)靜態(tài)工廠方法能產(chǎn)生該類型的對(duì)象。例如,假設(shè)編譯了模式之后,得到一個(gè)包含PurchaseOrder 模式派生接口的包c(diǎn)om.acme.foo 。要?jiǎng)?chuàng)建這類對(duì)象,客戶端應(yīng)用程序?qū)⑹褂孟铝泄S方法:

ObjectFactory objFactory = new ObjectFactory(); ? com.acme.foo.PurchaseOrder po = ??objFactory.createPurchaseOrder();

注意:由于當(dāng)contextPath 上有多個(gè)包時(shí),會(huì)產(chǎn)生多個(gè)ObjectFactory 類,所以如果你有多個(gè)contextPath上的包,在引用某個(gè)包中的ObjectFactory 類時(shí),必須使用完整的包名。


一旦客戶端應(yīng)用程序有模式派生對(duì)象的實(shí)例,它就能使用賦值方法來設(shè)置它的內(nèi)容。


注意:JAXB 提供程序?qū)崿F(xiàn)必須在每個(gè)包中生成一個(gè)類,這些包包含ObjectFactory 包的必要的對(duì)象工廠方法和newInstance( javaContentInterface ) 方法。


關(guān)于編組的更多信息

javax.xml.bind 包中的Marshaller 類使得客戶端應(yīng)用程序能夠?qū)ava內(nèi)容樹轉(zhuǎn)換成XML數(shù)據(jù)。編組一個(gè)使用工廠方法人為創(chuàng)建的內(nèi)容樹和反編組操作得到的內(nèi)容樹之間沒有什么區(qū)別。客戶端能夠?qū)ava內(nèi)容樹編組回到j(luò)ava.io.OutputStream 或java.io.Writer的XML數(shù)據(jù)中。編組過程能夠在注冊(cè)的ContentHandler 中生成SAX2 事件流或生成DOM Node 對(duì)象。

下面是一個(gè)簡(jiǎn)單的例子,它反編組一個(gè)XML文檔,然后在將它編組回去:

JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" ); ? // unmarshal from foo.xml Unmarshaller u = jc.createUnmarshaller(); FooObject fooObj = ??(FooObject)u.unmarshal( new File( "foo.xml" ) ); ? // marshal to System.out Marshaller m = jc.createMarshaller(); m.marshal( fooObj, System.out );

默認(rèn)情況下,在java.io.OutputStream 或 java.io.Writer中生成XML數(shù)據(jù)時(shí),Marshaller使用UTF-8 編碼。使用setProperty API 改變編組操作中輸出的編碼。客戶端應(yīng)用程序提供W3C XML 1.0 推薦中定義的有效的字符編碼名(http://www.w3.org/TR/2000/REC-xml-20001006#charencoding) 并且你的Java平臺(tái)支持它。

在調(diào)用編組API之前,不要求客戶端應(yīng)用程序驗(yàn)證Java內(nèi)容樹。同樣,也不要求根據(jù)源模式驗(yàn)證Java內(nèi)容樹以便將它編組回XML數(shù)據(jù)。不同的JAXB提供程序支持編組不同層的無效Java內(nèi)容樹,然而,所有的JAXB提供程序必須能夠?qū)⒂行У膬?nèi)容樹編組成XML數(shù)據(jù)。當(dāng)JAXB提供程序由于無效的內(nèi)容而不能完成編組操作時(shí)必須拋出MarshalException 。一些JAXB提供程序?qū)⑼耆С志幗M無效內(nèi)容,而其他一些將在遇到第一個(gè)驗(yàn)證錯(cuò)誤后就失效。

表 9-2 列出了Marshaller 類支持的屬性

9-2? ?Marshaller 屬性

屬性

描述

jaxb.encoding

值必須是java.lang.String;這是編組XML數(shù)據(jù)時(shí)使用的輸出編碼。默認(rèn)情況下,如果沒有指定它的屬性,Marshaller將使用"UTF-8"

jaxb.formatted.output

值必須是java.lang.Boolean。它控制Marshaller是否使用行分隔和縮進(jìn)格式化結(jié)果XML數(shù)據(jù)。如果它的值為true表示易讀縮進(jìn)的XML數(shù)據(jù),如果值為false表示未格式化的XML數(shù)據(jù)。如果沒有指定該屬性,Marshaller的默認(rèn)值為false (unformatted)

jaxb.schemaLocation

值必須是java.lang.String;它允許客戶端應(yīng)用程序指定生成的XML數(shù)據(jù)中的xsi:schemaLocation屬性。W3C XML Schema部分0:入門的第5.6節(jié)中通過一種易于理解的、非標(biāo)準(zhǔn)的形式介紹了schemaLocation屬性值的格式,并且在W3C XML Schema Part 1:結(jié)構(gòu)的第2.6節(jié)中規(guī)定了該屬性值的格式

jaxb.noNamespaceSchemaLocation

值必須是java.lang.String;允許客戶端應(yīng)用程序指定生成的XML數(shù)據(jù)中的xsi:noNamespaceSchemaLocation屬性

關(guān)于驗(yàn)證的更多信息

javax.xml.bind 包中的Validator 類主要用來在運(yùn)行時(shí)控制對(duì)內(nèi)容樹的驗(yàn)證。當(dāng)反編組過程結(jié)合了驗(yàn)證,并且驗(yàn)證成功,沒有產(chǎn)生任何驗(yàn)證錯(cuò)誤,那么就能確保輸出的文檔和結(jié)果內(nèi)容樹是有效的。相對(duì)比,編組過程中并不進(jìn)行驗(yàn)證。如果僅僅編組有效的內(nèi)容樹,這就能保證相對(duì)于源模式來說,生成的XML文檔總是有效的。

一些XML解析器如SAX和DOM允許取消模式驗(yàn)證功能,并且在一些情況下,為了提高處理速度并且/或者為了處理包含無效或不完整的內(nèi)容的文檔,你可能希望取消模式驗(yàn)證。通過在能使用JAXB的應(yīng)用程序中選澤的異常處理程序,JAXB支持這些處理方案。總的說來,如果一個(gè)JAXB實(shí)現(xiàn)不能確切完成反編組或編組,它將拋出一個(gè)異常,終止處理。


注意:Validator 類負(fù)責(zé)管理On-Demand驗(yàn)證(如下所示)。Unmarshaller 類負(fù)責(zé)管理反編組操作中的 Unmarshal-Time 驗(yàn)證。雖然沒有正式的方法能夠在編組操作中啟動(dòng)驗(yàn)證,Marshaller 可以監(jiān)測(cè)錯(cuò)誤,將它報(bào)告給它上面注冊(cè)的ValidationEventHandler 。


JAXB客戶端可以實(shí)現(xiàn)兩類驗(yàn)證:

  • Unmarshal-Time 驗(yàn)證 使得客戶端應(yīng)用程序能夠接收將XML數(shù)據(jù)反編組到Java內(nèi)容樹時(shí)監(jiān)測(cè)到的驗(yàn)證錯(cuò)誤消息和警告,并且跟驗(yàn)證的其他類型完全正交。使用Unmarshaller.setValidating方法來啟動(dòng)或終止它。所有的JAXB提供程序都要支持該操作。
  • On-Demand 驗(yàn)證 使得客戶端應(yīng)用程序能夠接收J(rèn)ava內(nèi)容樹中監(jiān)測(cè)到的驗(yàn)證錯(cuò)誤和警告。這點(diǎn)上,客戶端應(yīng)用程序能夠在Java內(nèi)容樹(或者它的任何子樹)上調(diào)用Validator.validate 方法。所有的JAXB提供程序都要支持該操作。

如果客戶端應(yīng)用程序沒有在調(diào)用驗(yàn)證、反編組或編組方法之前就在它的Validator 、Unmarshaller或 Marshaller 上設(shè)置事件處理程序,那么默認(rèn)的事件處理程序?qū)⒔邮沼龅降娜魏五e(cuò)誤通知。在遇到第一個(gè)錯(cuò)誤或致命錯(cuò)誤后,默認(rèn)的事件處理程序?qū)炱甬?dāng)前操作 (但是在接收到警告后將繼續(xù)該操作)

有三種方法能夠處理反編組、驗(yàn)證和編組操作過程中遇到的事件:

  • 使用默認(rèn)的事件處理程序。

如果沒有通過Validator、Unmarshaller或Marshaller上的setEventHandler API設(shè)置事件處理程序,將會(huì)使用默認(rèn)的事件處理程序。

  • 實(shí)現(xiàn)并注冊(cè)一個(gè)自定義的事件處理程序。

需要復(fù)雜的事件處理的客戶端應(yīng)用程序能夠?qū)崿F(xiàn)ValidationEventHandler 接口并使用Unmarshaller 和/或 Validator注冊(cè)它。

  • 使用ValidationEventCollector 工具。

為了方便,提供一個(gè)特定的事件處理程序,該處理程序僅僅收集反編組、驗(yàn)證和編組操作中創(chuàng)建的ValidationEvent 對(duì)象,并且將它們作為java.util.Collection返回給客戶端應(yīng)用程序。

根據(jù)客戶端應(yīng)用程序的配置,使用不同的方法來處理驗(yàn)證事件。然而,在一些情況下,JAXB提供程序不能正確地監(jiān)測(cè)并報(bào)告錯(cuò)誤。在這些情況下,JAXB提供程序?qū)alidationEvent 的驗(yàn)證性設(shè)置成 FATAL_ERROR ,表明將終止反編組、驗(yàn)證和編組操作。在收到致命錯(cuò)誤的通知后,默認(rèn)的事件處理程序和ValidationEventCollector工具類必須終止處理。接收到致命錯(cuò)誤的通知后,支持它們自己的ValidationEventHandler 客戶端應(yīng)用程序必須也終止處理。如果不終止處理,將會(huì)出現(xiàn)意想不到的情況。

XML Schema

由于XML模式是JAXB處理模型的一個(gè)重要的組件——并且由于其他數(shù)據(jù)綁定性能如JAXP使用DTD而不用模式——因此在這里了解一下XML模式的基本概念和它們的工作原理很有用。

XML Schema是描述XML文檔中允許的元素、屬性、實(shí)體和關(guān)系的強(qiáng)大的方法。DTD的一個(gè)更加強(qiáng)壯的選擇,XML模式的目標(biāo)是定義XML文檔的類,該類必須遵守一組特定的結(jié)構(gòu)和數(shù)據(jù)約束——也就是說,你可能希望為面向章的書、在線采購系統(tǒng)或個(gè)人數(shù)據(jù)庫定義不同的模式。在JAXB上下文中,將包含受到XML模式約束的XML文檔稱作文檔實(shí)例,并且將文檔實(shí)例內(nèi)部的結(jié)構(gòu)和數(shù)據(jù)叫做內(nèi)容樹。


注意:實(shí)際上,術(shù)語“文檔”并不總是精確的,因?yàn)?/span>XML實(shí)例文檔不一定要是形式完整的、自立的文檔文件;相反它具有流的形式,這些流可以是應(yīng)用程序之間傳遞的數(shù)據(jù)、數(shù)據(jù)庫字段集合、XML信息集合,其中信息塊包含了描述它們?cè)谀J浇Y(jié)構(gòu)中的位置的足夠信息。


下面的例子代碼來自于W3C Schema 部分 0:入門(http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/),顯示了一個(gè)XML文檔po.xml,是一個(gè)簡(jiǎn)單的購買訂單。

<?xml version="1.0"?>

<purchaseOrder orderDate="1999-10-20">

??<shipTo country="US">

????<name>Alice Smith</name>

????<street>123 Maple Street</street>

????<city>Mill Valley</city>

????<state>CA</state>

????<zip>90952</zip>

??</shipTo>

??<billTo country="US">

????<name>Robert Smith</name>

????<street>8 Oak Avenue</street>

????<city>Old Town</city>

????<state>PA</state>

????<zip>95819</zip>

??</billTo>

<comment>Hurry, my lawn is going wild!</comment>

??<items>

????<item partNum="872-AA">

??????<productName>Lawnmower</productName>

??????<quantity>1</quantity>

??????<USPrice>148.95</USPrice>

??????<comment>Confirm this is electric</comment>

????</item>

????<item partNum="926-AA">

??????<productName>Baby Monitor</productName>

??????<quantity>1</quantity>

??????<USPrice>39.98</USPrice>

??????<shipDate>1999-05-21</shipDate>

????</item>

??</items>

</purchaseOrder>

根元素purchaseOrder包含子元素shipTo, billTocommentitems。除了comment之外的所有子元素包含其他子元素。樹的葉子是子元素,如name, streetcitystate,它們不包含任何子元素。包含其他子元素或能接受屬性的元素叫做復(fù)合類型。僅包含PCDATA并且沒有子元素的元素叫做簡(jiǎn)單類型。

下面的采購模式中定義了po.xml中的復(fù)雜類型和一些簡(jiǎn)單類型。同樣,該例子模式來自于W3C Schema 部分 0:入門(http://www.w3.org/TR/2001/REC-xmlschema-0-20010502/).

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="purchaseOrder" type="PurchaseOrderType"/>

<xsd:element name="comment" type="xsd:string"/>

<xsd:complexType name="PurchaseOrderType">

??<xsd:sequence>

????<xsd:element name="shipTo" type="USAddress"/>

????<xsd:element name="billTo" type="USAddress"/>

????<xsd:element ref="comment" minOccurs="0"/>

????<xsd:element name="items" type="Items"/>

??</xsd:sequence>

??<xsd:attribute name="orderDate" type="xsd:date"/>

</xsd:complexType>

?

<xsd:complexType name="USAddress">

??<xsd:sequence>

????<xsd:element name="name" type="xsd:string"/>

????<xsd:element name="street" type="xsd:string"/>

????<xsd:element name="city" type="xsd:string"/>

????<xsd:element name="state" type="xsd:string"/>

????<xsd:element name="zip" type="xsd:decimal"/>

??</xsd:sequence>

??<xsd:attribute name="country" type="xsd:NMTOKEN"

??????fixed="US"/>

</xsd:complexType>

?

<xsd:complexType name="Items">

??<xsd:sequence>

????<xsd:element name="item" minOccurs="1"

??????????????maxOccurs="unbounded">

??????<xsd:complexType>

????????<xsd:sequence>

??????????<xsd:element name="productName"

????????????????????type="xsd:string"/>

??????????<xsd:element name="quantity">

????????????<xsd:simpleType>

??????????????<xsd:restriction base="xsd:positiveInteger">

????????????????<xsd:maxExclusive value="100"/>

??????????????</xsd:restriction>

????????????</xsd:simpleType>

??????????</xsd:element>

??????????<xsd:element name="USPrice" type="xsd:decimal"/>

??????????<xsd:element ref="comment" minOccurs="0"/>

??????????<xsd:element name="shipDate" type="xsd:date"

????????????????????minOccurs="0"/>

????????</xsd:sequence>

????????<xsd:attribute name="partNum" type="SKU"

????????????????????use="required"/>

??????</xsd:complexType>

????</xsd:element>

??</xsd:sequence>

</xsd:complexType>

?

<!-- Stock Keeping Unit, a code for identifying products -->

<xsd:simpleType name="SKU">

??<xsd:restriction base="xsd:string">

????<xsd:pattern value="/d{3}-[A-Z]{2}"/>

??</xsd:restriction>

</xsd:simpleType>

?

</xsd:schema>

在本例中,模式同DTD一樣包含main或根schema元素和幾個(gè)子元素elementcomplexTypesimpleType。和DTD不同,該模式也被指定成屬性數(shù)據(jù)類型,如decimaldatefixedstring。模式也受到如pattern valueminOccurspositiveInteger的約束。在DTD中,只能指定文本數(shù)據(jù)(PCDATACDATA)的數(shù)據(jù)類型, XML模式支持更加復(fù)雜的文本和數(shù)值數(shù)據(jù)類型和約束,這些在Java語言中都有直接對(duì)應(yīng)部分。

注意,本模式中的每個(gè)元素都有前綴xsd:,它和W3C XML Schema 命名空間相關(guān)。為此,命名空間聲明,xmlns:xsd="http://www.w3.org/2001/XMLSchema", 聲明的是schema元素的一個(gè)屬性。

支持命名空間是XML Schema的另一個(gè)重要的特征,因?yàn)樗鼮閰^(qū)分根據(jù)不同模式書寫的元素提供了一個(gè)方法或有其他不同的用途,但是它們可能和文檔中的其他元素有相同的名字。例如,假設(shè)你在你的模式中定義兩個(gè)命名空間,一個(gè)是foo,另外一個(gè)是bar。結(jié)合兩個(gè)XML 文檔,一個(gè)來自于開賬單數(shù)據(jù)庫,另一個(gè)來自于運(yùn)送數(shù)據(jù)庫,每個(gè)都建立在不同的模式下。通過在模式中指定命名空間,你可以區(qū)分foo:addressbar:address

表示XML內(nèi)容

本節(jié)介紹JAXB 如何將XML內(nèi)容表示成Java對(duì)象。本節(jié)主題如下:

·?? XML名字綁定到Java標(biāo)識(shí)符

·?? XML模式的Java表示

XML名字綁定到Java標(biāo)識(shí)符

XML模式語言使用XML名字——與XML1.0(第二版本) (http://www.w3.org/XML/)中定義的用來標(biāo)識(shí)模式組件的名字產(chǎn)品匹配的字符串。該字符串集合比有效的Java類、方法和約束標(biāo)識(shí)符的集合大。要解決該差異,JAXB使用幾個(gè)名字-映射算法。

JAXB名字-映射算法根據(jù)標(biāo)準(zhǔn)Java API設(shè)計(jì)指南將XML名字映射到Java標(biāo)識(shí)符,生成保留了到相應(yīng)模式連接的標(biāo)識(shí)符,并且不太可能產(chǎn)生沖突。

參考第10章,查看如何改變默認(rèn)XML名字映射。查看JAXB規(guī)范附錄C中關(guān)于JAXB命名算法的完整細(xì)節(jié)。

XML模式的Java表示

JAXB支持組合Java包中生成的類和接口。一個(gè)包包括:

·?? 名字,直接來自于XML命名空間URI或由XML命名空間URI綁定自定義指定。

·?? 一組Java內(nèi)容接口,表示模式中聲明的內(nèi)容模型。

·?? 一組Java元素接口,表示模式中出現(xiàn)的元素聲明。

·?? 包含如下內(nèi)容的一個(gè)ObjectFactory類:

o????? 每個(gè)Java內(nèi)容接口的實(shí)例工廠方法和包中的Java元素接口,例如,給定一個(gè)叫做FooJava內(nèi)容接口,取得的工廠方法是:

????public Foo createFoo() throws JAXBException;

o????? 動(dòng)態(tài)實(shí)例工廠分配器,創(chuàng)建指定的Java內(nèi)容接口的一個(gè)實(shí)例,例如:

?? ??????public Object newInstance(Class javaContentInterface) ???????? throws JAXBException;

o????? getPropertysetProperty API ,它們?cè)试S操縱指定提供程序的屬性。

·?? typesafe 枚舉類集合

·?? javadoc

綁定XML Schema

本節(jié)介紹了JAXB使用的默認(rèn)的XML-到-Java綁定。通過自定義綁定聲明可以通過自定義的綁定聲明全局覆蓋或逐層覆蓋所有這些綁定。本節(jié)主題如下:

·?? 簡(jiǎn)單類型定義

·?? 默認(rèn)的數(shù)據(jù)類型綁定

·?? 默認(rèn)的綁定規(guī)則摘要

查看JAXB 規(guī)范,以獲得JAXB綁定的完整信息。

簡(jiǎn)單類型定義

使用簡(jiǎn)單類型定義的模式組件通常和Java 屬性綁定。由于有多種這類模式組件,下列Java特征屬性(在模式組件中很常見)包括:

·?? 基本類型

·?? 集合類型,如果有的話

·?? 謂詞

其他Java特征屬性是使用simple 類型定義在模式組件中指定的。

默認(rèn)的數(shù)據(jù)類型綁定

Java語言提供了比XML模式更加豐富的數(shù)據(jù)類型集。表 9-3 列出了XML數(shù)據(jù)類型到JAXB中的Java數(shù)據(jù)類型的映射。

9-3 ?XML模式內(nèi)置數(shù)據(jù)類型的JAXB映射

XML Schema 類型

Java數(shù)據(jù)類型

xsd:string

java.lang.String

xsd:integer

java.math.BigInteger

xsd:int

int

xsd.long

long

xsd:short

short

xsd:decimal

java.math.BigDecimal

xsd:float

float

xsd:double

double

xsd:boolean

Boolean

xsd:byte

byte

xsd:Qname

javax.xml.namespace.QName

xsd:dateTime

java.util.Calendar

xsd:base64Binary

byte[]

xsd:hexBinary

byte[]

xsd:unsignedInt

long

xsd:unsignedShort

int

xsd:unsignedByte

short

xsd:time

Java.util.Calendar

xsd:date

Java.util.Calendar

xsd:anySimpleType

Java.lang.String

默認(rèn)的綁定規(guī)則摘要

JAXB綁定模型遵守下列默認(rèn)的綁定規(guī)則:

·?? 將下列內(nèi)容綁定到Java包:

o????? XML 命名空間URI

·?? 將下列XML模式組件綁定到Java內(nèi)容接口:

o????? 命名的復(fù)雜類型

o????? 元素聲明中匿名的內(nèi)部類型定義

·?? 綁定到類型安全枚舉類:

o????? 一個(gè)命名的簡(jiǎn)單類型定義,它有來自"xsd:NCName" 的基本類型,并且有枚舉面。

·?? 將下列XML Schema組件綁定到Java Element接口:

o????? Element 接口的全局元素聲明

o????? 能夠插入到全局內(nèi)容列表的本地元素聲明

·?? 綁定到Java屬性:

o????? 使用的屬性

o????? 元素引用或本地元素聲明的術(shù)語微粒

·?? 將重復(fù)出現(xiàn)和復(fù)雜的類型定義的模型組和混合的{content type}綁定到:

o????? 通用內(nèi)容屬性;具有Java實(shí)例表示元素信息項(xiàng)和字符數(shù)據(jù)項(xiàng)的列表內(nèi)容屬性

自定義JAXB綁定

使用自定義的綁定聲明可以在全局范圍或逐層地覆蓋默認(rèn)的JAXB綁定。如前面所介紹的,JAXB 使用默認(rèn)的綁定規(guī)則,可以通過下面兩種方法可以自定義這些綁定規(guī)則:

·?? XML模式的內(nèi)部注釋

·?? 傳遞給JAXB綁定編譯器的外部綁定自定義文件中的聲明

自定義JAXB綁定聲明也能不受XML schema中的XML規(guī)范約束自定義生成的JAXB類,讓它包括特定于Java改進(jìn),如類和包名映射。

你不需要為模式中的每個(gè)聲明提供一個(gè)綁定指令來生成Java類。例如,綁定編譯器使用通用的名字影射算法將XML名字綁定到Java編程語言能夠接受的名字。然而,如果在類中想要使用不同的名字模式,你可以明確自定義綁定聲明讓綁定編譯器生成不同的名字。在綁定聲明中可以進(jìn)行許多其他自定義,包括:

·?? 命名包、衍生類和方法

·?? 衍生類中的方法分配類型

·?? 選擇將哪個(gè)元素綁定到類

·?? 確定如何將屬性和元素聲明綁定到適當(dāng)內(nèi)容類的屬性

·?? 選擇每個(gè)屬性值或內(nèi)容規(guī)范的類型


注意: 依賴于默認(rèn)的JAXB綁定行為而不是為Java表示的每個(gè)XML Schema組件作出綁定聲明使得它能夠方便地跟上源模式中的變化。在多數(shù)情況下, 默認(rèn)的規(guī)則非常強(qiáng)壯,所以不需要任何自定義的綁定聲明就能產(chǎn)生可用的綁定。


第10章中給出了自定義JAXB綁定的代碼例子。

作用域

當(dāng)在綁定聲明中定義自定義值時(shí),就涉及到作用域。自定義值的作用域就是應(yīng)用它的模式元素集合。如果將一個(gè)自定義值應(yīng)用到一個(gè)模式元素,那么該模式元素就在自定義值的作用域內(nèi)。

表 9-4 列出了自定義的綁定的四個(gè)作用域。

9-4 自定義綁定的作用域

作用域

描述

Global

<globalBindings>中定義的自定義值具有全局作用域。全局作用域覆蓋了源模式中的所有模式元素和(遞歸的)源模式中包括或?qū)氲娜魏文J?/span>

Schema

<schemaBindings>中定義的自定義值具有模式作用域。模式作用域覆蓋了模式的目標(biāo)命名空間的所有模式元素

Definition

類型定義的綁定聲明中的自定義值和全局聲明具有定義作用域。定義作用域覆蓋了引用類型定義或全局聲明的所有模式元素

Component

如果自定義值僅應(yīng)用到綁定聲明注釋的模式元素,綁定聲明中的自定義值具有組件作用域

作用域繼承

不同的作用域形成了一個(gè)分類系統(tǒng)。該分類系統(tǒng)定義了自定義值的繼承和覆蓋語義。一個(gè)作用域內(nèi)的自定義值被另一個(gè)作用域的綁定聲明繼承使用,下面是繼承的層次關(guān)系:

·?? 模式作用域內(nèi)的模式元素繼承全局作用域內(nèi)定義的自定義值。

·?? 定義作用域內(nèi)的模式元素繼承模式或全局作用域內(nèi)定義的自定義值。

·?? 組件作用域內(nèi)的模式元素繼承定義、模式或全局作用域內(nèi)定義的自定義值。

相似的,一個(gè)作用域內(nèi)的自定義值能夠覆蓋繼承自另一個(gè)作用域的自定義值,如下所示:

·?? 模式作用域內(nèi)的值覆蓋繼承自全局作用域的值。

·?? 定義作用域內(nèi)的值覆蓋繼承自模式作用域或全局作用域的值。

·?? 組件作用域的值覆蓋繼承自定義、模式或全局作用域的值。?

?

?

==============================

JAXB生成一個(gè)XML文檔

開發(fā)者在線 Builder.com.cn 更新時(shí)間:2008-04-14

本文關(guān)鍵詞:文檔 xml JAXB JAVA

?一個(gè)XML 模式(Schema)XML語法表達(dá)了一個(gè)XML文檔的結(jié)構(gòu)。J2EE的開發(fā)者也許會(huì)需要一個(gè)符合XML模式的XML文檔。Java XML綁定架構(gòu)(JAXB)提供了一個(gè)綁定編譯器,xjc,來從一個(gè)XML模式中生成Java類。用JAXBxjc生成的Java類代表了在XML模式中不同的元素和復(fù)雜類型(complexType)。(一個(gè)復(fù)雜類型通過指定屬性和元素內(nèi)的元素來提供對(duì)一個(gè)元素的限定)。一個(gè)符合XML模式的XML文檔可以從這些Java類中構(gòu)建出來。

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

1.預(yù)設(shè)置
2.
概述
3.
XMl模式中生成Java
4.
Java類中生成一個(gè)XML文檔

????? 預(yù)設(shè)置

????? 為了用JAXB從一個(gè)XML模式中生成Java類,JAXB API類庫和xjc工具應(yīng)該存在CLASSPATH環(huán)境變量中。將Java Web服務(wù)開發(fā)包 (JWSDP) 1.5裝入一個(gè)安裝目錄中。將下列的.jar文件加入CLASSPATH環(huán)境變量中。

·<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服務(wù)開發(fā)包1.5的安裝目錄。把<JWSDP>/jaxb/bin加入PATH環(huán)境變量中。<JWSDP>/jaxb/bin目錄中包含了xjc編譯器。把<JWSDP>/jwsdp-shared/bin目錄加入到PATH環(huán)境變量中。<JWSDP>/jwsdp-shared/bin目錄中包含了setenv的批處理文件,它設(shè)置了JAVA_HOME, ANT_HOMEJWSDP_HOME這幾個(gè)環(huán)境變量。

?????? 概述

????? JAXB生成對(duì)應(yīng)著XML頂層元素和頂層復(fù)雜類型元素Java類和接口。在一個(gè)XML模式中,一個(gè)元素由<xs:element/>表示,一個(gè)復(fù)雜類型元素由<xs:complexType/>表示。這篇教程列舉了一個(gè)能夠表示一篇在科學(xué)雜志上發(fā)表的文章的示例模式,同時(shí)這個(gè)示例模式將會(huì)被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模式的構(gòu)造不被JAXB支持。如果這些不被支持的構(gòu)造包含在了模式中,那么當(dāng)你試圖用xjc來生成Java類時(shí)將會(huì)報(bào)錯(cuò)。下列模式元素不被支持: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工具基于此模式來綁定一個(gè)模式到Java類。針對(duì)本文的示例模式來進(jìn)行綁定的命令是:
>xjc catalog.xsd

????? xjc命令行接口的一些選項(xiàng)列如下:

-nv??????? 對(duì)于輸入的模式不執(zhí)行嚴(yán)格的XML驗(yàn)證
-b <file>???????
指定外部的綁定文件
-d <dir>???????
指定生成的文件的存放路徑
-p <pkg>???????
指定目標(biāo)包
-classpath <arg>????????
指定classpath
-use-runtime <pkg>??????? impl.runtime
包不被生成
-xmlschema???????
輸入的模式是一個(gè)W3C XML模式(默認(rèn))

?????? 對(duì)于示例模式catalog.xsd來說,xjc將會(huì)生成45個(gè)類,顯示在如下xjc的輸出中:

parsing a schema...
compiling a schema...
generatedimplruntimeErrorHandlerAdaptor.java
generatedimplruntimeMSVValidator.java
generatedimplruntimeNamespaceContext2.java
generatedimplruntimeUnmarshallableObject.java
generatedimplruntimeMarshallerImpl.java
generatedimplruntimeValidationContext.java
generatedimplruntimeUnmarshallerImpl.java
generatedimplruntimeDefaultJAXBContextImpl.java
generatedimplruntimeContentHandlerAdaptor.java
generatedimplruntimeGrammarInfoFacade.java
generatedimplruntimeUnmarshallingContext.java
generatedimplruntimeUnmarshallingEventHandlerAdaptor.java
generatedimplruntimeXMLSerializable.java
generatedimplruntimeDiscarder.java
generatedimplruntimePrefixCallback.java
generatedimplruntimeSAXMarshaller.java
generatedimplruntimeNamespaceContextImpl.java
generatedimplruntimeUnmarshallingEventHandler.java
generatedimplruntimeGrammarInfo.java
generatedimplruntimeInterningUnmarshallerHandler.java
generatedimplruntimeValidatableObject.java
generatedimplruntimeGrammarInfoImpl.java
generatedimplruntimeValidatingUnmarshaller.java
generatedimplruntimeValidatorImpl.java
generatedimplruntimeSAXUnmarshallerHandlerImpl.java
generatedimplruntimeXMLSerializer.java
generatedimplruntimeUtil.java
generatedimplruntimeSAXUnmarshallerHandler.java
generatedimplruntimeAbstractUnmarshallingEventHandlerImpl.java
generatedimplArticleImpl.java
generatedimplArticleTypeImpl.java
generatedimplCatalogImpl.java
generatedimplCatalogTypeImpl.java
generatedimplJAXBVersion.java
generatedimplJournalImpl.java
generatedimplJournalTypeImpl.java
generatedArticle.java
generatedArticleType.java
generatedCatalog.java
generatedCatalogType.java
generatedJournal.java
generatedJournalType.java
generatedObjectFactory.java
generatedbgm.ser
generatedjaxb.properties

?? 對(duì)于示例XML模式中的每個(gè)頂層xs:element和頂層xs:complexType,都對(duì)應(yīng)地生成了一個(gè)Java接口和一個(gè)Java類。同時(shí)也創(chuàng)建了一個(gè)工廠類(ObjectFactory.java,包含了創(chuàng)建接口對(duì)象的方法。可以在在篇文章的示例代碼文件jaxb-java-resources.zip中找到ObjectFactory.java類。

????? Catalog.java是對(duì)應(yīng)頂層元素catalog生成的接口。從模式的元素中生成的接口擴(kuò)展了javax.xml.bin.Elemnt類。

????? Catalog.java

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

????? CatalogType.java是對(duì)應(yīng)頂層復(fù)雜元素catalogType生成的接口。CatalogType接口對(duì)應(yīng)catalog元素的每個(gè)屬性指定了settergetter方法,還有對(duì)應(yīng)catalog元素中的journal元素的一個(gè)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是分別對(duì)應(yīng)Catalog.java CatalogType.java接口的實(shí)現(xiàn)類。

????? Java類中創(chuàng)建一個(gè)XML文檔

????? 這一節(jié)中,一個(gè)示例XMl文檔將會(huì)通進(jìn)JAXBJava類被創(chuàng)建。示例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類中創(chuàng)建一個(gè)CatalogImpl, 并且使用一個(gè)Marshaller(排列者)將CatalogImpl序列化來生成一個(gè)XML文檔。

????? 創(chuàng)建Marshaller(排列者)

????? 首先,導(dǎo)入javax.xml.bind包,其中包含了Marshaller, UnMarshaller, JAXBContext類。Marshaller類用來將一個(gè)Java類轉(zhuǎn)換為XML數(shù)據(jù)。UnMarshaller類轉(zhuǎn)換一個(gè)XML文檔成Java對(duì)象。

import javax.xml.bind.*;

? 創(chuàng)建一個(gè)JAXBContext

????? 一個(gè)JAXBContext對(duì)象被用來實(shí)現(xiàn)JAXB綁定框架的操作:marshal, unmarshalvalidate。應(yīng)用使用靜態(tài)方法newInstance(String contextPath)來創(chuàng)建一個(gè)新實(shí)例(對(duì)象)。contextPath指明一組由模式生成的接口的包名。

JAXBContext jaxbContext=JAXBContext.newInstance("generated");

????? 目錄generated包含了JAXB生成的類和接口

????? 使用createMarshaller方法創(chuàng)建一個(gè)MarshallerMarshaller類重載了marshal方法,可以將Java對(duì)象序列化(也就是,轉(zhuǎn)換一個(gè)Java對(duì)象到XML數(shù)據(jù))成SAX2事件,文檔對(duì)象模型(DOM),OutputStream, javax.xml.transform.Result或者java.io.Writer對(duì)象。

Marshaller marshaller=jaxbContext.createMarshaller();

????? XML文檔創(chuàng)建一個(gè)Java對(duì)象:CatalogImpl

????? 為了創(chuàng)建一個(gè)Java對(duì)象,首選生成一個(gè)ObjectFactoryObjectFactory將會(huì)創(chuàng)建一個(gè)實(shí)現(xiàn)類的實(shí)例。對(duì)于每一個(gè)模式生成的Java類,ObjectFactory中定義了一個(gè)靜態(tài)方法來創(chuàng)建一個(gè)它的對(duì)象。

ObjectFactory factory=new ObjectFactory();

????? 使用ObjectFactory類中的createCatalog來創(chuàng)建一個(gè)catalog元素。CatalogImplCatalog接口的實(shí)現(xiàn)類。
CatalogImpl catalog=(CatalogImpl)(factory
.createCatalog());

????? 使用CatalogImpl類中的setSection方法來設(shè)置catalog元素的section屬性。
catalog.setSection("Java Technology");

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

????? XML文檔創(chuàng)建一個(gè)Java對(duì)象:JournalImplArticleImpl

????? ObjectFactory類中的createJournal方法來創(chuàng)建一個(gè)jounal元素。JournalImplJournal接口的實(shí)現(xiàn)類。
JournalImpl journal=(JournalImpl)(factory.createJournal());

????? journal元素加入catalog元素。從CatalogImpl得到JournalImpljava.util.List,并把journal元素加入到List中。
java.util.List journalList=ca
talog.getJournal();journalList.add(journal);

????? 使用ObjectFactory類的createArticle方法來創(chuàng)建journal中的article元素。ArticleImplArticle接口的實(shí)現(xiàn)類。
ArticleImpl article=(ArticleImpl)(factory.createArticle());

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

????? setDate方法設(shè)置articledate屬性
article.setDate("January-2004");

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

????? setAuthor方法創(chuàng)建article元素的author屬性
article.setAuthor("Naveen
Balani");

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

????? 與創(chuàng)建article元素的過程相類似,其它article元素也將被創(chuàng)建用來生成示例XML文檔catalog.xml

????? Java對(duì)象序列化為一個(gè)XML文檔

????? Marshaller類中的marshal方法來將CatalogImpl對(duì)象序列化為一個(gè)XML文檔。CatalogImpl對(duì)象被序列化為一個(gè)OutputStream
marshaller.marshal(catalog, new FileOutputStream(xmlDocument));

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

????? 總結(jié)

????? JAXB提供了一個(gè)綁定編譯器xjc, 從一個(gè)模式中生成Java對(duì)象,然后這些Java對(duì)象可以序列化為一個(gè)XML文檔。但是,JAXB有一個(gè)限制:它不支持所有的XML模式結(jié)構(gòu)。

JAXBJava Architecture for XML Binding) 是一個(gè)業(yè)界的標(biāo)準(zhǔn),是一項(xiàng)可以根據(jù)XML Schema產(chǎn)生Java類的技術(shù)。該過程中,JAXB也提供了將XML實(shí)例文檔反向生成Java對(duì)象樹的方法,并能將Java對(duì)象樹的內(nèi)容重新寫到XML實(shí)例文檔。從另一方面來講,JAXB提供了快速而簡(jiǎn)便的方法將XML模式綁定到Java表示,從而使得Java開發(fā)者在Java應(yīng)用程序中能方便地結(jié)合XML數(shù)據(jù)和處理函數(shù)。

編輯本段使用

  “xjc”工具可以用來將XML模式或其他類型模式文件(Java 1.6試驗(yàn)性地支持RELAX NGDTD以及WSDL)轉(zhuǎn)換為Java類。Java類使用javax.xml.bind.annotation包下的Java 標(biāo)注,例如@XmlRootElement@XmlElementXML列表序列表示為java.util.List類型的屬性,通過JAXBContext可以創(chuàng)建Marshallers(將Java對(duì)象轉(zhuǎn)換成XML)和Unmarshallers(將XML解析為Java對(duì)象)。

  此外,JAXB包括了一個(gè)“schemagen”工具,能夠執(zhí)行“xjc”的反向操作,通過一組標(biāo)注的Java類創(chuàng)建一個(gè)XML模式。

編輯本段缺省的數(shù)據(jù)類型綁定

  下面的表格列出了JAXBXML數(shù)據(jù)類型和Java數(shù)據(jù)類型的映射。

  

XML Schema類型

Java數(shù)據(jù)類型

xsd:string

java.lang.String

xsd:positiveInteger

java.math.BigInteger

xsd:int

int

xsd:long

long

xsd:short

short

xsd:decimal

java.math.BigDecimal

xsd:float

float

xsd:double

double

xsd:boolean

boolean

xsd:byte

byte

xsd:QName

javax.xml.namespace.QName

xsd:dateTime

javax.xml.datatype.XMLGregorianCalendar

xsd:base64Binary

byte[]

xsd:hexBinary

byte[]

xsd:unsignedInt

long

xsd:unsignedShort

int

xsd:unsignedByte

short

xsd:time

javax.xml.datatype.XMLGregorianCalendar

xsd:date

javax.xml.datatype.XMLGregorianCalendar

xsd:g

javax.xml.datatype.XMLGregorianCalendar

xsd:anySimpleType

java.lang.Object

xsd:anySimpleType

java.lang.String

xsd:duration

javax.xml.datatype.Duration

xsd:NOTATION

javax.xml.namespace.QName

?

?

總結(jié)

以上是生活随笔為你收集整理的使用JAXB将XML Schema绑定到Java类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。