日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

使用JAXB将XML Schema绑定到Java类

發布時間:2024/4/17 asp.net 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用JAXB将XML Schema绑定到Java类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

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

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

本章介紹了JAXB體系結構、函數和核心概念。在學習第十章之前必須先閱讀本章。第十章給出了示例代碼和逐步使用JAXB的過程。

JAXB 體系結構

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

  • 體系結構概述
  • JAXB綁定過程
  • JAXB 綁定框架
  • 關于javax.xml.bind的更多信息
  • 關于反編組的更多信息
  • 關于編組的更多信息
  • 關于驗證的更多信息

體系結構概述

圖 9-1 給出了構成JAXB實現的組件。

圖 9-1 JAXB體系結構概述

如圖9-1所示,JAXB實現包含下列八個核心組件:

9-1 JAXB實現中的核心組件

組件

描述

XML Schema

XML模式使用XML語法描述XML文檔中元素、屬性和實體之間的關系。XML模式的目標是定義一個XML文檔類,該類必須堅持特定的結構規則和數據約束。例如你可能希望給面向章的書、在線采購系統或個人數據庫定義不同的模式。在JAXB上下文中,將包含數據的受到XML模式約束的XML文檔叫做文檔實例,并且將文檔實例中的結構和數據叫做內容樹

Binding
Declarations

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

Binding
Compiler

JAXB綁定編譯器是JAXB處理模型的核心。它的功能是將源XML模式轉換或綁定到Java編程語言中的一組JAXB內容類?;旧?#xff0c;可以通過將一個XML模式 (可以選擇使用自定義綁定聲明)用作輸入來運行JAXB綁定編譯器。綁定編譯器產生Java類,這些Java類映射到了源XML 模式中的約束條件

Binding
Framework
Implementation

JAXB綁定框架實現是運行時API,它提供了反編組、編組和驗證Java應用程序中的XML內容的接口。綁定框架包括javax.xml.bind包中的接口

Schema-Derived
Classes

這些是JAXB編譯器產生的模式派生類。根據輸入的模式將采用不同的類

Java
Application

JAXB上下文中,Java應用程序是客戶端應用程序,它使用JAXB綁定框架來反編組XML數據,驗證并修改Java內容對象,并將Java內容編組成XML數據。特別是,JAXB綁定框架包裝在一個能提供UI功能、XML轉換功能、數據處理或其他所需要的功能的大型Java應用程序中

XML Input
Documents

這是反編組出來用作JAXB綁定框架輸入的XML內容——即XML實例文檔,從這里將產生內容樹形式的Java表示。實際上,術語“文檔”不再是傳統意義上的文檔了,因為XML實例文檔不一定要是形式完整的、自立的文檔文件;相反它具有流的形式,這些流可以是應用程序之間傳遞的數據、數據庫字段集合、XML信息集合,其中信息塊包含了描述它們在模式結構中的位置的足夠信息。

?

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

XML Output
Documents

這是編組到XML文檔的XML內容。在JAXB編組包括解析XML內容對象樹并寫出一個XML文檔,該文檔是原始XML文檔的精確表示并且相對于原始模式來說是有效的。JAXB能夠將XML數據編組成XML 文檔、SAX內容處理程序和DOM節點。

JAXB綁定過程

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

圖 9-2 JAXB綁定過程步驟

JAXB數據綁定過程的常用步驟是:

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

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

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

4.?????? 生成內容樹。反編組過程產生從生成的JAXB類實例化而來的數據對象內容樹,該內容樹代表了源XML文檔的結構和內容。

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

6.?????? 處理內容。客戶端應用程序通過綁定編譯器產生的接口方法可以修改Java內容樹表示的XML數據。

7.?????? 編組。將處理過的內容樹編組到一個或多個XML輸出文檔中。在編組之前要驗證內容。

總而言之,使用JAXB涉及到兩個獨立的活動集:

  • 根據源模式生成并編譯JAXB類,并且建立一個實現這些類的應用程序。
  • 在JAXB綁定框架中運行應用程序,以反編組、處理、驗證和編組XML內容。

通常分時間分階段執行這兩個步驟。典型地,例如,需要在應用程序開發階段生成并編譯JAXB類,并且建立綁定實現,接著是部署階段,在該階段使用生成的JAXB類在“現場”產品環境中處理XML內容。


注意:反編組不是創建內容樹的唯一的方法。模式派生的內容類通過直接調用合適的工廠方法也支持按計劃構建內容樹。一旦創建了,任何時候都可以重新驗證內容樹的一部分或全部。查看示例應用程序 3 中的使用ObjectFactory 類直接給內容樹添加內容的例子。


JAXB綁定框架

JAXB綁定框架由三個Java包實現:

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

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

JAXBContext 類是Java應用程序到JAXB框架的入口點。JAXBContext 實例為反編組、編組和驗證操作使用的JAXB實現將XML元素名綁定到Java內容接口。

javax.xml.bind 包也定義了編組或反編組錯誤出現時、違反約束時及出現其他類型的錯誤時使用的豐富的驗證事件和異常類的層次結構。

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

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

關于javax.xml.bind的更多信息

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

JAXBContext 提供了一個抽象,該抽象可以管理實現反編組、編組和驗證操作必要的XML/Java綁定信息??蛻舳藨贸绦蛲ㄟ^newInstance(contextPath)方法得到該類的新實例。例如:

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

contextPath 參數包含一個Java包名,這些包包含模式派生的接口—特別是JAXB綁定編譯器產生的接口。該參數值初始化JAXBContext 對象,使得它能夠管理模式派生的接口。為此目的,JAXB提供程序實現必須提供一個包含下列特征的實現類:

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

注意:在每個包含模式派生類的包中,JAXB提供程序實現必須生成一個jaxb.properties 文件。該屬性文件必須包含一個叫做javax.xml.bind.context.factory 的屬性,它的值是實現createContext API的類的名字。

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


關于反編組的更多信息

javax.xml.bind 包中的Unmarshaller 類使得客戶端應用程序能夠將XML數據轉換成Java內容對象樹。模式的unmarshal 方法(在命名空間內)允許將模式中聲明的任何全局XML元素反編組成實例文檔的根。JAXBContext 對象允許在一組模式內合并全局元素(列在contextPath中)。由于模式集中的每個模式屬于不同的命名空間,將模式統一到反編組上下文中是獨立于命名空間的。這意味著客戶端應用程序能夠反編組contextPath 中列出的任何模式的實例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

客戶端應用程序也能明顯地生成Java內容樹而不是反編組現有XML數據。這樣做,應用程序必須能夠存取并了解contextPath 中的每個Java包中模式派生的ObjectFactory 類。對于每個模式派生Java類,將有一個靜態工廠方法能產生該類型的對象。例如,假設編譯了模式之后,得到一個包含PurchaseOrder 模式派生接口的包com.acme.foo 。要創建這類對象,客戶端應用程序將使用下列工廠方法:

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

注意:由于當contextPath 上有多個包時,會產生多個ObjectFactory 類,所以如果你有多個contextPath上的包,在引用某個包中的ObjectFactory 類時,必須使用完整的包名。


一旦客戶端應用程序有模式派生對象的實例,它就能使用賦值方法來設置它的內容。


注意:JAXB 提供程序實現必須在每個包中生成一個類,這些包包含ObjectFactory 包的必要的對象工廠方法和newInstance( javaContentInterface ) 方法。


關于編組的更多信息

javax.xml.bind 包中的Marshaller 類使得客戶端應用程序能夠將Java內容樹轉換成XML數據。編組一個使用工廠方法人為創建的內容樹和反編組操作得到的內容樹之間沒有什么區別。客戶端能夠將Java內容樹編組回到java.io.OutputStream 或java.io.Writer的XML數據中。編組過程能夠在注冊的ContentHandler 中生成SAX2 事件流或生成DOM Node 對象。

下面是一個簡單的例子,它反編組一個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 );

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

在調用編組API之前,不要求客戶端應用程序驗證Java內容樹。同樣,也不要求根據源模式驗證Java內容樹以便將它編組回XML數據。不同的JAXB提供程序支持編組不同層的無效Java內容樹,然而,所有的JAXB提供程序必須能夠將有效的內容樹編組成XML數據。當JAXB提供程序由于無效的內容而不能完成編組操作時必須拋出MarshalException 。一些JAXB提供程序將完全支持編組無效內容,而其他一些將在遇到第一個驗證錯誤后就失效。

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

9-2? ?Marshaller 屬性

屬性

描述

jaxb.encoding

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

jaxb.formatted.output

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

jaxb.schemaLocation

值必須是java.lang.String;它允許客戶端應用程序指定生成的XML數據中的xsi:schemaLocation屬性。W3C XML Schema部分0:入門的第5.6節中通過一種易于理解的、非標準的形式介紹了schemaLocation屬性值的格式,并且在W3C XML Schema Part 1:結構的第2.6節中規定了該屬性值的格式

jaxb.noNamespaceSchemaLocation

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

關于驗證的更多信息

javax.xml.bind 包中的Validator 類主要用來在運行時控制對內容樹的驗證。當反編組過程結合了驗證,并且驗證成功,沒有產生任何驗證錯誤,那么就能確保輸出的文檔和結果內容樹是有效的。相對比,編組過程中并不進行驗證。如果僅僅編組有效的內容樹,這就能保證相對于源模式來說,生成的XML文檔總是有效的。

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


注意:Validator 類負責管理On-Demand驗證(如下所示)。Unmarshaller 類負責管理反編組操作中的 Unmarshal-Time 驗證。雖然沒有正式的方法能夠在編組操作中啟動驗證,Marshaller 可以監測錯誤,將它報告給它上面注冊的ValidationEventHandler 。


JAXB客戶端可以實現兩類驗證:

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

如果客戶端應用程序沒有在調用驗證、反編組或編組方法之前就在它的Validator 、Unmarshaller或 Marshaller 上設置事件處理程序,那么默認的事件處理程序將接收遇到的任何錯誤通知。在遇到第一個錯誤或致命錯誤后,默認的事件處理程序將掛起當前操作 (但是在接收到警告后將繼續該操作)

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

  • 使用默認的事件處理程序。

如果沒有通過Validator、Unmarshaller或Marshaller上的setEventHandler API設置事件處理程序,將會使用默認的事件處理程序。

  • 實現并注冊一個自定義的事件處理程序。

需要復雜的事件處理的客戶端應用程序能夠實現ValidationEventHandler 接口并使用Unmarshaller 和/或 Validator注冊它。

  • 使用ValidationEventCollector 工具。

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

根據客戶端應用程序的配置,使用不同的方法來處理驗證事件。然而,在一些情況下,JAXB提供程序不能正確地監測并報告錯誤。在這些情況下,JAXB提供程序將ValidationEvent 的驗證性設置成 FATAL_ERROR ,表明將終止反編組、驗證和編組操作。在收到致命錯誤的通知后,默認的事件處理程序和ValidationEventCollector工具類必須終止處理。接收到致命錯誤的通知后,支持它們自己的ValidationEventHandler 客戶端應用程序必須也終止處理。如果不終止處理,將會出現意想不到的情況。

XML Schema

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

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


注意:實際上,術語“文檔”并不總是精確的,因為XML實例文檔不一定要是形式完整的、自立的文檔文件;相反它具有流的形式,這些流可以是應用程序之間傳遞的數據、數據庫字段集合、XML信息集合,其中信息塊包含了描述它們在模式結構中的位置的足夠信息。


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

<?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, billTo、commentitems。除了comment之外的所有子元素包含其他子元素。樹的葉子是子元素,如name, street、citystate,它們不包含任何子元素。包含其他子元素或能接受屬性的元素叫做復合類型。僅包含PCDATA并且沒有子元素的元素叫做簡單類型。

下面的采購模式中定義了po.xml中的復雜類型和一些簡單類型。同樣,該例子模式來自于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元素和幾個子元素element、complexTypesimpleType。和DTD不同,該模式也被指定成屬性數據類型,如decimal、date、fixedstring。模式也受到如pattern value、minOccurspositiveInteger的約束。在DTD中,只能指定文本數據(PCDATACDATA)的數據類型, XML模式支持更加復雜的文本和數值數據類型和約束,這些在Java語言中都有直接對應部分。

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

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

表示XML內容

本節介紹JAXB 如何將XML內容表示成Java對象。本節主題如下:

·?? XML名字綁定到Java標識符

·?? XML模式的Java表示

XML名字綁定到Java標識符

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

JAXB名字-映射算法根據標準Java API設計指南將XML名字映射到Java標識符,生成保留了到相應模式連接的標識符,并且不太可能產生沖突。

參考第10章,查看如何改變默認XML名字映射。查看JAXB規范附錄C中關于JAXB命名算法的完整細節。

XML模式的Java表示

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

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

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

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

·?? 包含如下內容的一個ObjectFactory類:

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

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

o????? 動態實例工廠分配器,創建指定的Java內容接口的一個實例,例如:

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

o????? getPropertysetProperty API ,它們允許操縱指定提供程序的屬性。

·?? typesafe 枚舉類集合

·?? javadoc

綁定XML Schema

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

·?? 簡單類型定義

·?? 默認的數據類型綁定

·?? 默認的綁定規則摘要

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

簡單類型定義

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

·?? 基本類型

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

·?? 謂詞

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

默認的數據類型綁定

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

9-3 ?XML模式內置數據類型的JAXB映射

XML Schema 類型

Java數據類型

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

默認的綁定規則摘要

JAXB綁定模型遵守下列默認的綁定規則:

·?? 將下列內容綁定到Java包:

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

·?? 將下列XML模式組件綁定到Java內容接口:

o????? 命名的復雜類型

o????? 元素聲明中匿名的內部類型定義

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

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

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

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

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

·?? 綁定到Java屬性:

o????? 使用的屬性

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

·?? 將重復出現和復雜的類型定義的模型組和混合的{content type}綁定到:

o????? 通用內容屬性;具有Java實例表示元素信息項和字符數據項的列表內容屬性。

自定義JAXB綁定

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

·?? XML模式的內部注釋

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

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

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

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

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

·?? 選擇將哪個元素綁定到類

·?? 確定如何將屬性和元素聲明綁定到適當內容類的屬性

·?? 選擇每個屬性值或內容規范的類型


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


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

作用域

當在綁定聲明中定義自定義值時,就涉及到作用域。自定義值的作用域就是應用它的模式元素集合。如果將一個自定義值應用到一個模式元素,那么該模式元素就在自定義值的作用域內。

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

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

作用域

描述

Global

<globalBindings>中定義的自定義值具有全局作用域。全局作用域覆蓋了源模式中的所有模式元素和(遞歸的)源模式中包括或導入的任何模式

Schema

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

Definition

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

Component

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

作用域繼承

不同的作用域形成了一個分類系統。該分類系統定義了自定義值的繼承和覆蓋語義。一個作用域內的自定義值被另一個作用域的綁定聲明繼承使用,下面是繼承的層次關系:

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

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

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

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

·?? 模式作用域內的值覆蓋繼承自全局作用域的值。

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

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

?

?

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

JAXB生成一個XML文檔

開發者在線 Builder.com.cn 更新時間:2008-04-14

本文關鍵詞:文檔 xml JAXB JAVA

?一個XML 模式(Schema)XML語法表達了一個XML文檔的結構。J2EE的開發者也許會需要一個符合XML模式的XML文檔。Java XML綁定架構(JAXB)提供了一個綁定編譯器,xjc,來從一個XML模式中生成Java類。用JAXBxjc生成的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_HOMEJWSDP_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...
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

?? 對于示例XML模式中的每個頂層xs:element和頂層xs:complexType,都對應地生成了一個Java接口和一個Java類。同時也創建了一個工廠類(ObjectFactory.java,包含了創建接口對象的方法??梢栽谠谄恼碌氖纠a文件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元素的每個屬性指定了settergetter方法,還有對應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文檔將會通進JAXBJava類被創建。示例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, unmarshalvalidate。應用使用靜態方法newInstance(String contextPath)來創建一個新實例(對象)。contextPath指明一組由模式生成的接口的包名。

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

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

????? 使用createMarshaller方法創建一個MarshallerMarshaller類重載了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元素。CatalogImplCatalog接口的實現類。
CatalogImpl catalog=(CatalogImpl)(factory
.createCatalog());

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

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

????? XML文檔創建一個Java對象:JournalImplArticleImpl

????? ObjectFactory類中的createJournal方法來創建一個jounal元素。JournalImplJournal接口的實現類。
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方法來創建journal中的article元素。ArticleImplArticle接口的實現類。
ArticleImpl article=(ArticleImpl)(factory.createArticle());

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

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

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

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

????? article元素加入journal元素中。從JournalImpl中得到ArticleImpljava.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是輸出的XMLjava.io.File對象,它代表的是本節一開始所展示的XML文檔。JAXBConstructor.java,這個程序用來從Java類中生成一個XML文檔,也在這篇文章的示例代碼文件中。

????? 總結

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

JAXBJava Architecture for XML Binding) 是一個業界的標準,是一項可以根據XML Schema產生Java類的技術。該過程中,JAXB也提供了將XML實例文檔反向生成Java對象樹的方法,并能將Java對象樹的內容重新寫到XML實例文檔。從另一方面來講,JAXB提供了快速而簡便的方法將XML模式綁定到Java表示,從而使得Java開發者在Java應用程序中能方便地結合XML數據和處理函數。

編輯本段使用

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

  此外,JAXB包括了一個“schemagen”工具,能夠執行“xjc”的反向操作,通過一組標注的Java類創建一個XML模式。

編輯本段缺省的數據類型綁定

  下面的表格列出了JAXBXML數據類型和Java數據類型的映射。

  

XML Schema類型

Java數據類型

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

?

?

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。