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绑定过程
1. 生成类。将XML模式放入JAXB绑定编译器,以产生基于该模式的JAXB类。
3. 反编组。JAXB绑定框架反编组根据原始模式中的约束编写的XML文档。注意JAXB也支持反编组来自除了文件/文档之外XML数据,如DOM节点、字符串缓冲、SAX Source等等。
4. 生成内容树。反编组过程产生从生成的JAXB类实例化而来的数据对象内容树,该内容树代表了源XML文档的结构和内容。
5. 验证(可选)。反编组过程中,可以在生成内容树之前验证源XML文档。注意,如果在第6步中修改内容树,下面,你也能使用JAXB验证操作在将内容编组到XML文档之前验证变化。
6. 处理内容。客户端应用程序通过绑定编译器产生的接口方法可以修改Java内容树表示的XML数据。
7. 编组。将处理过的内容树编组到一个或多个XML输出文档中。在编组之前要验证内容。
通常分时间分阶段执行这两个步骤。典型地,例如,需要在应用程序开发阶段生成并编译JAXB类,并且建立绑定实现,接着是部署阶段,在该阶段使用生成的JAXB类在“现场”产品环境中处理XML内容。
注意:反编组不是创建内容树的唯一的方法。模式派生的内容类通过直接调用合适的工厂方法也支持按计划构建内容树。一旦创建了,任何时候都可以重新验证内容树的一部分或全部。查看示例应用程序 3 中的使用ObjectFactory
类直接给内容树添加内容的例子。
JAXB绑定框架
javax.xml.bind
包定义Unmarshaller
、Validator
和Marshaller
类,它们是提供各自操作的辅助对象。
JAXBContext
类是Java应用程序到JAXB框架的入口点。JAXBContext
实例为反编组、编组和验证操作使用的JAXB实现将XML元素名绑定到Java内容接口。
javax.xml.bind
包也定义了编组或反编组错误出现时、违反约束时及出现其他类型的错误时使用的丰富的验证事件和异常类的层次结构。
下面将详细介绍JAXB绑定框架中的主要的包javax.bind.xml
。
关于javax.xml.bind的更多信息
主要绑定框架包javax.xml.bind
提供的三个核心功能是编组、反编组和验证。到绑定框架的主要的客户端入口点是JAXBContext
类。
JAXBContext
提供了一个抽象,该抽象可以管理实现反编组、编组和验证操作必要的XML/Java绑定信息。客户端应用程序通过newInstance(contextPath)
方法得到该类的新实例。例如:
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提供程序将完全支持编组无效内容,而其他一些将在遇到第一个验证错误后就失效。
关于验证的更多信息
javax.xml.bind
包中的Validator
类主要用来在运行时控制对内容树的验证。当反编组过程结合了验证,并且验证成功,没有产生任何验证错误,那么就能确保输出的文档和结果内容树是有效的。相对比,编组过程中并不进行验证。如果仅仅编组有效的内容树,这就能保证相对于源模式来说,生成的XML文档总是有效的。
一些XML解析器如SAX和DOM允许取消模式验证功能,并且在一些情况下,为了提高处理速度并且/或者为了处理包含无效或不完整的内容的文档,你可能希望取消模式验证。通过在能使用JAXB的应用程序中选泽的异常处理程序,JAXB支持这些处理方案。总的说来,如果一个JAXB实现不能确切完成反编组或编组,它将抛出一个异常,终止处理。
注意:Validator
类负责管理On-Demand验证(如下所示)。Unmarshaller
类负责管理反编组操作中的 Unmarshal-Time 验证。虽然没有正式的方法能够在编组操作中启动验证,Marshaller
可以监测错误,将它报告给它上面注册的ValidationEventHandler
。
如果客户端应用程序没有在调用验证、反编组或编组方法之前就在它的Validator
、Unmarshaller
或 Marshaller
上设置事件处理程序,那么默认的事件处理程序将接收遇到的任何错误通知。在遇到第一个错误或致命错误后,默认的事件处理程序将挂起当前操作 (但是在接收到警告后将继续该操作)
如果没有通过Validator
、Unmarshaller
或Marshaller
上的setEventHandler
API设置事件处理程序,将会使用默认的事件处理程序。
需要复杂的事件处理的客户端应用程序能够实现ValidationEventHandler
接口并使用Unmarshaller
和/或 Validator
注册它。
为了方便,提供一个特定的事件处理程序,该处理程序仅仅收集反编组、验证和编组操作中创建的ValidationEvent
对象,并且将它们作为java.util.Collection
返回给客户端应用程序。
根据客户端应用程序的配置,使用不同的方法来处理验证事件。然而,在一些情况下,JAXB提供程序不能正确地监测并报告错误。在这些情况下,JAXB提供程序将ValidationEvent
的验证性设置成 FATAL_ERROR
,表明将终止反编组、验证和编组操作。在收到致命错误的通知后,默认的事件处理程序和ValidationEventCollector
工具类必须终止处理。接收到致命错误的通知后,支持它们自己的ValidationEventHandler
客户端应用程序必须也终止处理。如果不终止处理,将会出现意想不到的情况。
由于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包含子元素shipTo, billTo、comment和items。除了comment之外的所有子元素包含其他子元素。树的叶子是子元素,如name, street、city和state,它们不包含任何子元素。包含其他子元素或能接受属性的元素叫做复合类型。仅包含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>
在本例中,模式同DTD一样包含main或根schema元素和几个子元素element、complexType和simpleType。和DTD不同,该模式也被指定成属性数据类型,如decimal、date、fixed和string。模式也受到如pattern value、minOccurs和positiveInteger的约束。在DTD中,只能指定文本数据(PCDATA和CDATA)的数据类型, XML模式支持更加复杂的文本和数值数据类型和约束,这些在Java语言中都有直接对应部分。
注意,本模式中的每个元素都有前缀xsd:,它和W3C XML Schema 命名空间相关。为此,命名空间声明,xmlns:xsd="http://www.w3.org/2001/XMLSchema", 声明的是schema元素的一个属性。
支持命名空间是XML Schema的另一个重要的特征,因为它为区分根据不同模式书写的元素提供了一个方法或有其他不同的用途,但是它们可能和文档中的其他元素有相同的名字。例如,假设你在你的模式中定义两个命名空间,一个是foo,另外一个是bar。结合两个XML 文档,一个来自于开账单数据库,另一个来自于运送数据库,每个都建立在不同的模式下。通过在模式中指定命名空间,你可以区分foo:address和bar: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表示
· 名字,直接来自于XML命名空间URI或由XML命名空间URI绑定自定义指定。
o 每个Java内容接口的实例工厂方法和包中的Java元素接口,例如,给定一个叫做Foo
的Java内容接口,取得的工厂方法是:
o 动态实例工厂分配器,创建指定的Java内容接口的一个实例,例如:
o getProperty
和setProperty
API ,它们允许操纵指定提供程序的属性。
绑定XML Schema
本节介绍了JAXB使用的默认的XML-到-Java绑定。通过自定义绑定声明可以通过自定义的绑定声明全局覆盖或逐层覆盖所有这些绑定。本节主题如下:
· 简单类型定义
简单类型定义
使用简单类型定义的模式组件通常和Java 属性绑定。由于有多种这类模式组件,下列Java特征属性(在模式组件中很常见)包括:
其他Java特征属性是使用simple
类型定义在模式组件中指定的。
默认的数据类型绑定
Java语言提供了比XML模式更加丰富的数据类型集。表 9-3 列出了XML数据类型到JAXB中的Java数据类型的映射。
默认的绑定规则摘要
o 一个命名的简单类型定义,它有来自"xsd:NCName
" 的基本类型,并且有枚举面。
· 将下列XML Schema组件绑定到Java Element接口:
· 将重复出现和复杂的类型定义的模型组和混合的{content type}
绑定到:
o 通用内容属性;具有Java实例表示元素信息项和字符数据项的列表内容属性。
自定义JAXB绑定
使用自定义的绑定声明可以在全局范围或逐层地覆盖默认的JAXB绑定。如前面所介绍的,JAXB 使用默认的绑定规则,可以通过下面两种方法可以自定义这些绑定规则:
自定义JAXB绑定声明也能不受XML schema中的XML规范约束自定义生成的JAXB类,让它包括特定于Java改进,如类和包名映射。
你不需要为模式中的每个声明提供一个绑定指令来生成Java类。例如,绑定编译器使用通用的名字影射算法将XML名字绑定到Java编程语言能够接受的名字。然而,如果在类中想要使用不同的名字模式,你可以明确自定义绑定声明让绑定编译器生成不同的名字。在绑定声明中可以进行许多其他自定义,包括:
注意: 依赖于默认的JAXB绑定行为而不是为Java表示的每个XML Schema组件作出绑定声明使得它能够方便地跟上源模式中的变化。在多数情况下, 默认的规则非常强壮,所以不需要任何自定义的绑定声明就能产生可用的绑定。
作用域
当在绑定声明中定义自定义值时,就涉及到作用域。自定义值的作用域就是应用它的模式元素集合。如果将一个自定义值应用到一个模式元素,那么该模式元素就在自定义值的作用域内。
表 9-4 列出了自定义的绑定的四个作用域。
作用域继承
不同的作用域形成了一个分类系统。该分类系统定义了自定义值的继承和覆盖语义。一个作用域内的自定义值被另一个作用域的绑定声明继承使用,下面是继承的层次关系:
· 定义作用域内的模式元素继承模式或全局作用域内定义的自定义值。
· 组件作用域内的模式元素继承定义、模式或全局作用域内定义的自定义值。
相似的,一个作用域内的自定义值能够覆盖继承自另一个作用域的自定义值,如下所示:
==============================
用JAXB生成一个XML文档
开发者在线 Builder.com.cn 更新时间:2008-04-14
一个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...
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),包含了创建接口对象的方法。可以在在篇文章的示例代码文件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模式结构。
JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。
编辑本段使用
“xjc”工具可以用来将XML模式或其他类型模式文件(Java 1.6试验性地支持RELAX NG,DTD以及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模式。
编辑本段缺省的数据类型绑定
下面的表格列出了JAXB中XML数据类型和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 |