自定义 JAXB 绑定
以下部分描述了一些示例,这些示例基于基本示例中演示的概念。
本部分的 Object 是说明如何使用自定义绑定声明来自定义 JAXB 绑定,该声明是通过以下两种方式之一进行的:
-
作为 注解 在 XMLPattern 中内联
-
作为外部文件中的语句传递给 JAXB 绑定编译器
与基本的 JAXB 示例中的示例着重于各自Main\.java
类文件中的 Java 代码不同,此处的示例着重于在生成 Pattern 派生的 Java 绑定类之前对 XMLPattern 进行的自定义。
Note:
当前必须手动进行 JAXB 绑定定制。 JAXB 技术的目标之一是标准化绑定声明的格式,从而可以创建自定义工具并在 JAXB 实现之间提供标准的交换格式。
本节介绍可以对 JAXB 绑定和验证方法进行的自定义。有关更多信息,请参见JAXB Specification。
Why Customize?
在大多数情况下,由 JAXB 绑定编译器生成的默认绑定就足够了。但是,在某些情况下,您可能需要修改默认绑定。其中一些包括:
-
为基于 Pattern 的 JAXB 包,类,方法和常量创建 API 文档:通过将自定义 Javadoc 工具 注解 添加到 Pattern 中,您可以解释特定于实现的概念,准则和规则。
-
为默认 XML 名称到 Java 标识符 Map 无法自动处理的情况提供语义上有意义的自定义名称;例如:
-
解决名称冲突(如 JAXB 规范的附录 D.2.1 中所述)。请注意,JAXB 绑定编译器检测并报告所有名称冲突。
-
为无效的 Java 标识符提供类型安全的枚举常量的名称;例如,对整数值进行枚举。
-
当未命名模型组绑定到 Java 属性或类时,为它们的 Java 表示提供更好的名称。
-
提供比默认情况下从目标名称空间 URI 派生的有意义的包名称。
-
-
覆盖默认绑定;例如:
-
指定模型组必须绑定到类而不是列表。
-
指定可以将固定属性绑定到 Java 常量。
-
覆盖 XML Schema 内置数据类型到 Java 数据类型的指定默认绑定。在某些情况下,您可能想引入一个替代 Java 类,它可以表示内置 XML Schema 数据类型的其他 Feature。
-
Customization Overview
本节说明一些 JAXB 核心定制概念:
-
内联和外部定制
-
范围,继承和优先级
-
Customization syntax
-
自定义名称空间前缀
内联和外部定制
对默认 JAXB 绑定的自定义是以传递给 JAXB 绑定编译器的 绑定声明 的形式进行的。这些绑定声明可以通过以下两种方式之一进行:
-
作为源 XMLPattern 中的内联 注解
-
作为外部绑定定制文件中的声明
对于某些用户而言,使用内联自定义更为容易,因为您可以在自定义对其应用的架构的上下文中看到自定义。相反,使用外部绑定自定义文件可以使您自定义 JAXB 绑定而无需修改源 Pattern,并使您可以轻松地一次将自定义应用于多个 Pattern 文件。
Note:
您可以组合两种类型的定制。例如,您可以在内联 注解 中包含对外部绑定定制文件的引用。但是,您不能在同一架构元素上同时声明内联和外部定制。
以下各节将对每种类型的自定义进行更详细的描述:
Inline Customizations
通过 XMLPattern 文件中的内联 绑定声明 对 JAXB 绑定进行的自定义采用嵌入在 Pattern\<xsd:annotation\>
元素中的\<xsd:appinfo\>
元素的形式(xsd:
是 XMLPattern 名称空间前缀,如 W3C XML Schema 第 1 部分:结构中所定义) )。以下示例显示了内联定制的一般形式:
<xs:annotation>
<xs:appinfo>
<!--
...
binding declarations .
...
-->
</xs:appinfo>
</xs:annotation>
自定义应用在架构中声明它们的位置。例如,特定元素级别的声明仅适用于该元素。请注意,XMLPattern 名称空间前缀必须与\<annotation\>
和\<appinfo\>
声明标记一起使用。在前面的示例中,xs:
用作名称空间前缀,因此声明被标记为\<xs:annotation\>
和\<xs:appinfo\>
。
外部绑定自定义文件
通过使用包含绑定声明的外部文件对 JAXB 绑定进行定制,其格式如下例所示:
<jxb:bindings schemaLocation = "xs:anyURI">
<jxb:bindings node = "xs:string">*
<!-- binding declaration -->
<jxb:bindings>
</jxb:bindings>
-
schemaLocation
是对远程 Pattern 的 URI 引用。 -
node
是 XPath 1.0 表达式,用于标识schemaLocation
中与给定绑定声明关联的架构节点。
例如,JAXB 绑定声明文件中的第一个schemaLocation
/node
声明指定了 Pattern 名称和根 Pattern 节点:
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
</jxb:bindings>
后续的schemaLocation
/node
声明,例如上一个 Pattern 示例中名为ZipCodeType
的simpleType
元素,采用以下形式:
<jxb:bindings node="//xs:simpleType [@name='ZipCodeType']">
绑定自定义文件格式
绑定自定义文件必须为 ASCII 文本。名称或 extensions 无关紧要;尽管本章中使用的典型 extensions 是\.xjb
。
将自定义文件传递给 JAXB 绑定编译器
使用以下语法,将包含绑定声明的定制文件传递给 JAXB Binding 编译器xjc
:
xjc -b file schema
其中,file 是绑定定制文件的名称,而 schema 是您要传递给绑定编译器的 Pattern 的名称。
您可以有一个包含多个 Pattern 自定义项的绑定文件,也可以将自定义项分成多个绑定文件。例如:
xjc schema1.xsd schema2.xsd schema3.xsd \
-b bindings123.xjb
xjc schema1.xsd schema2.xsd schema3.xsd \
-b bindings1.xjb \
-b bindings2.xjb \
-b bindings3.xjb
注意,在命令行上 Pattern 文件和绑定文件的 Sequences 无关紧要;尽管每个绑定自定义文件都必须在命令行上带有自己的\-b
switch。
有关一般xjc
编译器选项的更多信息,请参见JAXB 编译器选项。
外部绑定自定义的限制
有一些规则适用于在外部绑定定制文件中进行的绑定声明,而不适用于在源 Pattern 中内联进行的类似声明:
- 绑定定制文件必须以
jxb:bindings version
属性以及 JAXB 和 XMLSchema 名称空间的属性开头:
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
-
必须使用指定
schemaLocation
和node
属性的jxb:bindings
声明,以 XPath 表示法明确标识要应用绑定声明的远程 Pattern: -
schemaLocation
指定对远程 Pattern 的 URI 引用。node
指定一个 XPath 1.0 表达式,该表达式标识schemaLocation
中与给定绑定声明关联的 Pattern 节点;对于绑定定制文件中的初始jxb:bindings
声明,此节点通常为"/xs:schema"
。
类似地,必须使用 XPath 表示法指定要在其中应用定制的 Pattern 中的各个节点。例如:
<jxb:bindings node="//xs:complexType [@name='USAddress']">
在这种情况下,绑定编译器将自定义应用于该节点,就像声明是内联嵌入节点的\<xs:appinfo\>
元素中一样。
总结这些规则,仅在以下三种情况下,JAXB 绑定编译器才能识别外部绑定元素\<jxb:bindings\>
进行处理:
-
当其父项是
\<xs:appinfo\>
元素时。 -
当它是另一个
\<jxb:bindings\>
元素的祖先时。 -
当它是文档的根元素时。以
\<jxb:bindings\>
元素为根的 XML 文档称为外部绑定声明文件。
范围,继承和优先级
可以在四个不同级别(或范围)自定义或覆盖默认的 JAXB 绑定。
下图说明了自定义声明的继承和优先级。具体来说,朝向金字塔顶部的声明会继承并取代位于其下方的声明。
组件声明继承并取代了定义声明;定义声明继承并取代 Schema 声明;和 Schema 声明继承并替代 Global 声明。
Customization Syntax
下一节将描述四种类型的 JAXB 绑定声明的语法,XML 到 Java 数据类型绑定声明的语法以及定制名称空间前缀。
全局绑定声明
全局范围自定义使用\<globalBindings\>
声明。全局范围自定义的语法如下:
<globalBindings>
[ collectionType = "collectionType" ]
[ fixedAttributeAsConstantProperty = "true" | "false" | "1" | "0" ]
[ generateIsSetMethod = "true" | "false" | "1" | "0" ]
[ enableFailFastCheck = "true" | "false" | "1" | "0" ]
[ choiceContentProperty = "true" | "false" | "1" | "0" ]
[ underscoreBinding = "asWordSeparator" | "asCharInWord" ]
[ typesafeEnumBase = "typesafeEnumBase" ]
[ typesafeEnumMemberName = "generateName" | "generateError" ]
[ enableJavaNamingConventions = "true" | "false"
| "1" | "0" ]
[ bindingStyle = "elementBinding" | "modelGroupBinding" ]
[ <javaType> ... </javaType> ]*
</globalBindings>
-
collectionType
可以是indexed
或任何实现java\.util\.List
的完全限定的类名。 -
fixedAttributeAsConstantProperty
可以是true
,false
,1
或0
。默认值为false
。 -
generateIsSetMethod
可以是true
,false
,1
或0
。默认值为false
。 -
enableFailFastCheck
可以是true
,false
,1
或0
。如果enableFailFastCheck
是true
或1
并且 JAXB 实现支持此可选检查,则在设置属性时执行类型约束检查。默认值为false
。请注意,JAXB 实现不支持快速故障验证。 -
choiceContentProperty
可以是true
,false
,1
或0
。默认值为false
。当bindingStyle
为elementBinding
时choiceContentProperty
不相关。因此,如果将bindingStyle
指定为elementBinding
,则choiceContentProperty
必须导致无效的自定义。 -
underscoreBinding
可以是asWordSeparator
或asCharInWord
。默认值为asWordSeparator
。 -
typesafeEnumBase
可以是 QName 的列表,每个 QName 必须解析为简单的类型定义。默认值为xs:NCName
。有关simpleType
定义到 Javatypesafe enum
类的本地化 Map 的信息,请参见类型安全枚举绑定声明。 -
typesafeEnumMemberName
可以是generateError
或generateName
。默认值为generateError
。 -
enableJavaNamingConventions
可以是true
,false
,1
或0
。默认值为true
。 -
bindingStyle
可以是elementBinding
或modelGroupBinding
。默认值为elementBinding
。 -
\<javaType\>
可以是零个或多个 javaType 绑定声明。有关更多信息,请参见javaType 绑定声明。
\<globalBindings\>
声明仅在顶级schema
元素的annotation
元素中有效。在任何给定的架构或绑定声明文件中,\<globalBindings\>
声明只能有一个实例。如果一个源 Pattern 包含或导入第二个源 Pattern,则必须在第一个源 Pattern 中声明\<globalBindings\>
声明。
Pattern 绑定声明
Pattern 范围自定义使用\<schemaBindings\>
声明。Pattern 范围自定义的语法为:
<schemaBindings>
[ <package> package </package> ]
[ <nameXmlTransform> ... </nameXmlTransform> ]*
</schemaBindings>
<package
[ name = "packageName" ]
[ <javadoc> ... </javadoc> ]
</package>
<nameXmlTransform>
[ <typeName
[ suffix="suffix" ]
[ prefix="prefix" ] /> ]
[ <elementName
[ suffix="suffix" ]
[ prefix="prefix" ] /> ]
[ <modelGroupName
[ suffix="suffix" ]
[ prefix="prefix" ] /> ]
[ <anonymousTypeName
[ suffix="suffix" ]
[ prefix="prefix" ] /> ]
</nameXmlTransform>
如上所示,\<schemaBinding\>
声明包括两个子组件:
-
\<package\>\.\.\.\</package\>
指定程序包的名称,并根据需要指定 Pattern 派生类的 API 文档的位置。 -
\<nameXmlTransform\>\.\.\.\</nameXmlTransform\>
指定要应用的自定义。
类绑定声明
\<class\>
绑定声明使您可以自定义架构元素到 Java 内容interface或 Java Element
interface的绑定。 \<class\>
声明可用于自定义:
-
Pattern 派生的 Java interface的名称
-
Pattern 派生的 Java 内容interface的实现类
\<class\>
自定义的语法为:
<class
[ name = "className"]
[ implClass= "implClass" ] >
[ <javadoc> ... </javadoc> ]
</class>
-
name
是派生的 Java interface的名称。它必须是有效的 Java interface名称,并且不能包含程序包前缀。包前缀是从包的当前值继承的。 -
implClass
是 className 的实现类的名称,并且必须包含完整的程序包名称。 -
\<javadoc\>
元素为 Pattern 派生的 Java interface指定 Javadoc 工具 注解。在此处 Importing 的字符串 必须使用CDATA
或\<
来转义嵌入的 HTML 标签。
属性绑定声明
\<property\>
绑定声明使您可以自定义 XMLPattern 元素对其属性的 Java 表示形式的绑定。定制的范围可以在定义级别或组件级别,具体取决于指定\<property\>
绑定声明的位置。
\<property\>
自定义的语法为:
<property
[ name = "propertyName"]
[ collectionType = "propertyCollectionType" ]
[ fixedAttributeAsConstantProperty = "true" |
"false" | "1" | "0" ]
[ generateIsSetMethod = "true" |
"false" | "1" | "0" ]
[ enableFailFastCheck ="true" |
"false" | "1" | "0" ]
[ <baseType> ... </baseType> ]
[ <javadoc> ... </javadoc> ]
</property>
<baseType>
<javaType> ... </javaType>
</baseType>
-
name
定义定制值propertyName
;它必须是有效的 Java 标识符。 -
collectionType
定义自定义值propertyCollectionType
,这是属性propertyCollectionType
的集合类型。如果指定,则该属性可以是indexed
或实现java\.util\.List
的任何完全限定的类名。 -
fixedAttributeAsConstantProperty
定义自定义值fixedAttributeAsConstantProperty
。该值可以是true
,false
,1
或0
。 -
generateIsSetMethod
定义自定义值generateIsSetMethod
。该值可以是true
,false
,1
或0
。 -
enableFailFastCheck
定义自定义值enableFailFastCheck
。该值可以是true
,false
,1
或0
。请注意,JAXB 实现不支持快速故障验证。 -
\<javadoc\>
为该属性的 getter 方法自定义 Javadoc 工具 注解。
javaType 绑定声明
\<javaType\>
声明提供了一种自定义 XML 数据类型与 Java 数据类型之间的转换的方法。 XML 提供的数据类型比 Java 多,因此\<javaType\>
声明使您可以在默认的 JAXB 绑定不能充分表示您的 Pattern 时指定自定义数据类型绑定。
目标 Java 数据类型可以是 Java 内置数据类型,也可以是特定于应用程序的 Java 数据类型。如果将特定于应用程序的 Java 数据类型用作目标,则您的实现还必须提供解析和打印方法来解组和编组数据。为此,JAXB 规范支持parseMethod
和printMethod
:
-
在解组期间调用
parseMethod
,以将 Importing 文档中的字符串 转换为目标 Java 数据类型的值。 -
编组期间将调用
printMethod
,以将目标类型的值转换为词汇表示形式。
如果您希望定义自己的数据类型转换,则 JAXB 定义一个静态类DatatypeConverter
,以帮助解析和打印 XML Schema 内置数据类型的有效词法表示。
\<javaType\>
自定义的语法为:
<javaType name= "javaType"
[ xmlType= "xmlType" ]
[ hasNsContext = "true" | "false" ]
[ parseMethod= "parseMethod" ]
[ printMethod= "printMethod" ]>
-
name
是xmlType
绑定到的 Java 数据类型。 -
xmlType
是javaType
绑定到的 XML Schema 数据类型的名称;当\<javaType\>
声明的父级是\<globalBindings\>
时,此属性是必需的。 -
hasNsContext
允许将名称空间上下文指定为打印或解析方法的第二个参数;可以是true
,false
,1
或0
。默认情况下,此属性为false
,并且在大多数情况下,无需更改它。 -
parseMethod
是在解组期间要调用的 parse 方法的名称。 -
printMethod
是在编组期间要调用的打印方法的名称。
\<javaType\>
声明可用于:
-
\<globalBindings\>
声明 -
简单类型定义,
GlobalBindings
和\<basetype\>
声明的 注解 元素 -
\<property\>
声明
有关在自定义数据类型转换器类中如何实现\<javaType\>
声明和DatatypeConverterInterface
interface的示例,请参见MyDatatypeConverter Class。
Typesafe 枚举绑定声明
类型安全枚举声明提供了将 XML simpleType
元素 Map 到 Java typesafe enum
类的本地化方法。您可以进行两种类型的类型安全枚举声明:
-
\<typesafeEnumClass\>
可让您将整个simpleType
类 Map 到typesafe enum
类。 -
\<typesafeEnumMember\>
可让您将simpleType
类的选定成员 Map 到typesafe enum
类。
在这两种情况下,这种类型的定制都有两个主要限制:
-
使用此绑定声明只能自定义具有枚举构面的
simpleType
定义。 -
此自定义一次仅适用于单个
simpleType
定义。要在全局级别上 Map 相似的simpleType
定义集,请使用\<globalBindings\>
声明中的typesafeEnumBase
属性,如Global 约束力声明中所述。
\<typesafeEnumClass\>
自定义的语法为:
<typesafeEnumClass
[ name = "enumClassName" ]
[ <typesafeEnumMember> ... </typesafeEnumMember> ]*
[ <javadoc> enumClassJavadoc </javadoc> ]
</typesafeEnumClass>
-
name
必须是有效的 Java 标识符,并且不能具有程序包前缀。 -
您可以在
\<typesafeEnumClass\>
声明中嵌入零个或多个\<typesafeEnumMember\>
声明。 -
\<javadoc\>
为枚举类定制 Javadoc 工具 注解。
\<typesafeEnumMember\>
自定义的语法为:
<typesafeEnumMember
name = "enumMemberName">
[ value = "enumMemberValue" ]
[ <javadoc> enumMemberJavadoc </javadoc> ]
</typesafeEnumMember>
-
name
必须始终指定,并且必须是有效的 Java 标识符。 -
value
必须是在 wecePattern 中指定的枚举值。 -
\<javadoc\>
自定义枚举常量的 Javadoc 工具 注解。
对于内联 注解,必须在\<simpleType\>
元素的 注解 元素中指定\<typesafeEnumClass\>
声明。 \<typesafeEnumMember\>
必须在枚举成员的 注解 元素中指定。这使枚举成员可以独立于枚举类进行自定义。
有关类型安全的枚举设计 Pattern 的信息,请参见约书亚·布洛赫(Joshua Bloch)在 Oracle 技术网上的有效 Java 编程的示例章节。。
javadoc 绑定声明
\<javadoc\>
声明使您可以将自定义 Javadoc 工具 注解 添加到源自架构的 JAXB 包,类,interface,方法和字段。请注意,\<javadoc\>
声明不能全局应用;它们仅作为其他绑定自定义项的子元素有效。
\<javadoc\>
自定义的语法为:
<javadoc>
Contents in <b>Javadoc<\b> format.
</javadoc>
or
<javadoc>
<<![CDATA[Contents in <b>Javadoc<\b> format ]]>
</javadoc>
请注意,在包级别应用的\<javadoc\>
声明中的文档字符串 必须包含\<body\>
打开和关闭标签;例如:
<jxb:package
name="primer.myPo">
<jxb:javadoc>
<![CDATA[<body>
Package level documentation for generated package primer.myPo.
</body>]]>
</jxb:javadoc>
</jxb:package>
自定义命名空间前缀
所有标准 JAXB 绑定声明必须在名称空间前缀之前,该名称空间前缀 Map 到 JAXB 名称空间 URI http://java.sun.com/xml/ns/jaxb。例如,在此示例中,使用jxb:
。为此,要使用标准 JAXB 绑定声明**进行自定义的任何 Pattern 都必须在 Pattern 文件的顶部包括 JAXB 名称空间声明和 JAXB 版本号。例如,在po\.xsd
中的“定制内联”示例中,名称空间声明如下:
<xsd:schema
xmlns:xsd= "http://www.w3.org/2001/XMLSchema"
xmlns:jxb= "http://java.sun.com/xml/ns/jaxb"
jxb:version="1.0">
具有jxb
名称空间前缀的绑定声明采用以下形式:
<xsd:annotation>
<xsd:appinfo>
<jxb:globalBindings
binding declarations />
<jxb:schemaBindings>
...
binding declarations .
...
</jxb:schemaBindings>
</xsd:appinfo>
</xsd:annotation>
请注意,在此示例中,globalBindings
和schemaBindings
声明分别用于指定全局范围和架构范围的自定义。这些自定义范围在范围,继承和优先级中有更详细的描述。
自定义内联示例
“定制内联”示例说明了通过对名为po\.xsd
的 XMLPattern 的内联 注解 进行的一些基本自定义。此外,此示例实现了自定义数据类型转换器类MyDatatypeConverter\.java
,该类说明了\<javaType\>
自定义中用于处理自定义数据类型转换的 print 和 parse 方法。
总结这个例子:
-
po\.xsd
是包含内联绑定定制的 XMLPattern。 -
MyDatatypeConverter\.java
是 Java 类文件,可实现po\.xsd
中的\<javaType\>
定制指定的打印和解析方法。 -
Main\.java
是 Customize Inline 示例中的主要类文件,它使用 JAXB 编译器生成的架构派生的类。
使用 Ant 构建和运行定制内联示例
要使用 Ant 编译并运行 Customize Inline 示例,请在终端窗口中,转到 jaxb-ri-install /samples/inline\-customize/
目录,然后键入以下内容:
ant
下一节将更详细地描述此示例中的键自定义和自定义MyDatatypeConverter\.java
类。
Customized Schema
“定制内联”示例中使用的定制 Pattern 位于文件 jaxb-ri-install /samples/inline\-customize/po\.xsd
中。自定义项位于\<xsd:annotation\>
标记中。
全局绑定声明
以下代码示例显示了po\.xsd
中的globalBindings
声明:
<jxb:globalBindings
fixedAttributeAsConstantProperty="true"
collectionType="java.util.Vector"
typesafeEnumBase="xsd:NCName"
choiceContentProperty="false"
typesafeEnumMemberName="generateError"
bindingStyle="elementBinding"
enableFailFastCheck="false"
generateIsSetMethod="false"
underscoreBinding="asCharInWord"/>
在此示例中,除collectionType
之外,所有值均设置为默认值。
-
将
fixedAttributeAsConstantProperty
设置为 true 表示所有固定属性都应绑定到 Java 常量。默认情况下,固定属性 Map 到简单属性或集合属性,以较合适的为准。 -
将
collectionType
设置为java\.util\.Vector
可以指定在内部将生成的实现类中的所有列表表示为向量。请注意,您为collectionType
指定的类名称必须实现java\.util\.List
,并且可以由newInstance
调用。 -
如果
typesafeEnumBase
设置为xsd:string
,则这是一种全局方法,它指定默认情况下必须将直接或间接地从xsd:string
派生并具有枚举构面的所有simple
类型定义绑定到typesafe enum
。如果typesafeEnumBase
设置为空字符串(""
),则默认情况下,没有simple
类型定义绑定到typesafe enum
类。typesafeEnumBase
的值可以是除xsd:boolean
和两个二进制类型之外的任何原子简单类型定义。 -
JAXB 实现不支持
enableFailFastCheck
属性。
Note:
使用类型安全的枚举类使您能够将架构枚举值 Map 到 Java 常量,这使得可以对 Java 常量而不是字符串 值进行比较。
Pattern 绑定声明
以下代码显示了po\.xsd
中的 Pattern 绑定声明:
<jxb:schemaBindings>
<jxb:package name="primer.myPo">
<jxb:javadoc>
<![CDATA[<body>
Package level documentation for generated package primer.myPo.
</body>]]>
</jxb:javadoc>
</jxb:package>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
-
\<jxb:package name="primer\.myPo"/\>
指定primer\.myPo
作为在其中生成架构派生类的包。 -
\<jxb:nameXmlTransform\>
指定默认情况下,所有生成的 Java 元素interface都将Element
附加到生成的名称之后。例如,当针对该 Pattern 运行 JAXB 编译器时,将生成元素interfaceCommentElement
和PurchaseOrderElement
。相反,如果没有这种定制,则默认绑定将生成Comment
和PurchaseOrder
。如果 Pattern 在不同的符号空间中使用相同的名称,则此定制很有用;例如,在全局元素和类型定义中。在这种情况下,通过这种自定义,您可以使用一个声明来解决冲突,而不必使用单独的绑定声明来单独解决每个冲突。 -
\<jxb:javadoc\>
为primer\.myPo
包指定自定义的 Javadoc 工具 注解。请注意,与类级别的\<javadoc\>
声明不同,如以下示例所示,在包级别进行\<javadoc\>
声明时,必须包括开始和结束\<body\>
标记。
类绑定声明
以下代码显示了po\.xsd
中的类绑定声明:
<xsd:complexType name="PurchaseOrderType">
<xsd:annotation>
<xsd:appinfo>
<jxb:class name="POType">
<jxb:javadoc>
A <b>Purchase Order</b>
consists of addresses and items.
</jxb:javadoc>
</jxb:class>
</xsd:appinfo>
</xsd:annotation>
<!-- ... -->
</xsd:complexType>
Pattern 派生的POType
类的 Javadoc 工具 注解 将包含描述"A <b\>Purchase Order</b\> consists of addresses and items\."
。<
用于转义\<b\>
HTML 标记上的左括号。
Note:
如上一个示例所示,当在complexType
定义的appinfo
元素中指定\<class\>
自定义时,complexType
定义将绑定到 Java 内容interface。
稍后在po\.xsd
中,在该类级别上声明了另一个\<javadoc\>
定制,但是这次 HTML 字符串 使用CDATA
进行了转义:
<xsd:annotation>
<xsd:appinfo>
<jxb:class>
<jxb:javadoc>
<![CDATA[
First line of documentation for a
<b>USAddress</b>.]]>
</jxb:javadoc>
</jxb:class>
</xsd:appinfo>
</xsd:annotation>
Note:
如果要在\<jaxb:javadoc\>
自定义中包含 HTML 标签,则必须将数据括在CDATA
部分中,或使用<
转义所有左尖括号。有关更多信息,请参见XML 1.0 第二版。
属性绑定声明
这里特别有趣的是generateIsSetMethod
定制,它会生成两个附加的属性方法isSetQuantity
和unsetQuantity
。这些方法使 Client 端应用程序可以区分 Pattern 默认值和在实例文档中显式出现的值。
例如,在po\.xsd
中:
<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"
default="10">
<xsd:annotation>
<xsd:appinfo>
<jxb:property
generateIsSetMethod="true"/>
</xsd:appinfo>
</xsd:annotation>
<!-- ... -->
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
@generateIsSetMethod
应用于quantity
元素,该元素绑定到Items\.ItemType
interface内的属性。 unsetQuantity
和isSetQuantity
方法在Items\.ItemType
interface中生成。
MyDatatypeConverter Class
下例中显示的 jaxb-ri-install /samples/inline\-customize/src/inlinecustomize/primer/MyDatatypeConverter
类提供了一种使用\<javaType\>
定制来定制 XML 数据类型与 Java 数据类型之间的转换的方法。
package primer;
import java.math.BigInteger;
import javax.xml.bind.DatatypeConverter;
public class MyDatatypeConverter {
public static short parseIntegerToShort(String value) {
BigInteger result = DatatypeConverter.parseInteger(value);
return (short)(result.intValue());
}
public static String printShortToInteger(short value) {
BigInteger result = BigInteger.valueOf(value);
return DatatypeConverter.printInteger(result);
}
public static int parseIntegerToInt(String value) {
BigInteger result = DatatypeConverter.parseInteger(value);
return result.intValue();
}
public static String printIntToInteger(int value) {
BigInteger result = BigInteger.valueOf(value);
return DatatypeConverter.printInteger(result);
}
};
以下代码显示了在po\.xsd
的\<javaType\>
声明中如何引用MyDatatypeConverter
类:
<xsd:simpleType name="ZipCodeType">
<xsd:annotation>
<xsd:appinfo>
<jxb:javaType name="int"
parseMethod="primer.MyDatatypeConverter.parseIntegerToInt"
printMethod="primer.MyDatatypeConverter.printIntTo Integer" />
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
在此示例中,jxb:javaType
绑定声明将此类型的默认 JAXB 绑定重写为java\.math\.BigInteger
。就 Customize Inline 示例而言,对ZipCodeType
的限制(具体来说,有效的美国邮政编码限制为五位数字)使得所有有效值都可以适合 Java 基本数据类型int
。还要注意,由于在ZipCodeType
中声明了\<jxb:javaType name="int"/\>
,因此自定义应用于引用该simpleType
定义的所有 JAXB 属性,包括getZip
和setZip
方法。
DataType 转换器示例
DataType Converter 示例类似于 Customize Inline 示例。与 Customize Inline 示例一样,Datatype Converter 示例中的定制是通过使用 XMLPattern 中的应用程序po\.xsd
的内联绑定声明来进行的。
Customize Inline 和 DataType Converter 示例的全局,架构和包以及大多数类自定义是相同的。 “数据类型转换器”示例与“定制内联”示例不同的地方是用于将 XML 数据转换为 Java int
数据类型的parseMethod
和printMethod
。
具体而言,不是使用自定义MyDataTypeConverter
类中的方法来执行这些数据类型转换,而是使用“数据类型转换器”示例使用javax\.xml\.bind\.DatatypeConverter
提供的内置方法:
<xsd:simpleType name="ZipCodeType">
<xsd:annotation>
<xsd:appinfo>
<jxb:javaType
name="int"
parseMethod="javax.xml.bind.DatatypeConverter.parseInt"
printMethod="javax.xml.bind.DatatypeConverter.printInt"/>
</xsd:appinfo>
</xsd:annotation>
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="10000"/>
<xsd:maxInclusive value="99999"/>
</xsd:restriction>
</xsd:simpleType>
使用 Ant 构建和运行数据类型转换器示例
要使用 Ant 编译并运行 DataType Converter 示例,请在终端窗口中,转到 jaxb-ri-install /samples/datatypeconverter/
目录并键入以下内容:
ant
绑定声明文件
以下各节提供有关绑定声明文件的信息:
JAXB 版本,名称空间和架构属性
所有 JAXB 绑定声明文件必须以以下内容开头:
-
JAXB 版本号
-
Namespace declarations
-
Pattern 名称和节点
bindings\.xjb
中的版本,名称空间和架构声明如下:
<jxb:bindings
version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings
schemaLocation="po.xsd"
node="/xs:schema">
<!-- ...
binding-declarations
... -->
</jxb:bindings>
<!--
schemaLocation="po.xsd"
node="/xs:schema" -->
</jxb:bindings>
JAXB 版本号
根元素为\<jaxb:bindings\>
的 XML 文件被视为外部绑定文件。根元素必须指定其绑定声明必须遵守的 JAXB 版本属性;特别是根\<jxb:bindings\>
元素必须包含<jxb:version\>
声明或version
属性。相反,当以内联方式进行绑定声明时,将 JAXB 版本号作为\<xsd:schema\>
声明的属性:
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
jxb:version="1.0">
Namespace Declarations
如JAXB 版本,命名空间和架构属性所示,外部绑定声明文件中的名称空间声明同时包含 JAXB 名称空间和 XMLSchema 名称空间。请注意,本示例中使用的前缀实际上可以是您想要的任何前缀。重要的是要始终使用在文件的后续声明中在此处定义的任何前缀。
架构名称和架构节点
JAXB 版本,命名空间和架构属性中代码的第四行指定此绑定声明文件所应用的架构的名称,以及自定义将首先生效的架构节点。该文件中的后续绑定声明可以引用架构中的特定节点,但是该第一个声明应将架构整体包含在内;例如,在bindings\.xjb
中:
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
全局和架构绑定声明
数据类型转换器示例的bindings\.xjb
中的全局架构绑定声明与po\.xsd
中的全局架构绑定声明相同。唯一的区别是,因为po\.xsd
中的声明是内联的,所以必须将它们嵌入\<xs:appinfo\>
元素中,而\<xs:appinfo\>
元素又嵌入\<xs:annotation\>
元素中。不需要在外部绑定文件中以这种方式嵌入声明。
<jxb:globalBindings
fixedAttributeAsConstantProperty="true"
collectionType="java.util.Vector"
typesafeEnumBase="xs:NCName"
choiceContentProperty="false"
typesafeEnumMemberName="generateError"
bindingStyle="elementBinding"
enableFailFastCheck="false"
generateIsSetMethod="false"
underscoreBinding="asCharInWord"/>
<jxb:schemaBindings>
<jxb:package name="primer.myPo">
<jxb:javadoc>
<![CDATA[<body>
Package level documentation for generated package
primer.myPo.</body>]]>
</jxb:javadoc>
</jxb:package>
<jxb:nameXmlTransform>
<jxb:elementName suffix="Element"/>
</jxb:nameXmlTransform>
</jxb:schemaBindings>
相比之下,在po\.xsd
中用于 DataType Converter 示例的语法是:
<xsd:annotation>
<xsd:appinfo>
<jxb:globalBindings
...
binding-declarations
...
<jxb:schemaBindings>
...
binding-declarations
...
</jxb:schemaBindings>
</xsd:appinfo>
</xsd:annotation>
Class Declarations
对于数据类型转换器示例,bindings\.xjb
中的类级别绑定声明与po\.xsd
中的类似声明有两种不同:
-
与
bindings\.xjb
中的所有其他绑定声明一样,您无需将自定义内容嵌入架构\<xsd:appinfo\>
元素中。 -
您必须指定应用定制的 Pattern 节点。这种声明的一般语法是:
<jxb:bindings node="//node-type[@name='node-name']">
例如,以下代码显示了名为complexType
的complexType
的绑定声明。
<jxb:bindings node="//xs:complexType [@name='USAddress']">
<jxb:class>
<jxb:javadoc>
<![CDATA[
First line of documentation for a <b>USAddress</b>.
]]>
</jxb:javadoc>
</jxb:class>
<jxb:bindings node=".//xs:element [@name='name']">
<jxb:property name="toName"/>
</jxb:bindings>
<jxb:bindings node=".//xs:element [@name='zip']">
<jxb:property name="zipCode"/>
</jxb:bindings>
</jxb:bindings>
<!--
node="//xs:complexType
[@name='USAddress']" -->
请注意,在此示例中,USAddress
是子元素name
和zip
的父元素,因此\</jxb:bindings\>
标签将子元素的bindings
声明和类级别的javadoc
声明括起来。
外部自定义示例
“外部定制”示例与“数据类型转换器”示例相同,不同之处在于,“外部定制”示例中的绑定声明是通过使用外部绑定声明文件而不是在源 XMLPattern 中内联来进行的。
“外部定制”示例中使用的绑定定制文件是 jaxb-ri-install /samples/external\-customize/binding\.xjb
。
本节将bindings\.xjb
中的自定义声明与 XMLType po\.xsd
中使用的类似声明(在 DataType Converter 示例中)进行了比较。两组声明实现了完全相同的结果。
使用 Ant 构建和运行外部定制示例
要使用 Ant 编译并运行 External Customize 示例,请在终端窗口中,转到 jaxb-ri-install /samples/external\-customize/
目录,然后键入以下内容:
ant