# 自定义 JAXB 绑定

> 原文： [https://docs.oracle.com/javase/tutorial/jaxb/intro/custom.html](https://docs.oracle.com/javase/tutorial/jaxb/intro/custom.html)

以下部分描述了基于 Basic 示例中演示的概念的几个示例。

本节的目的是说明如何使用自定义绑定声明自定义 JAXB 绑定，使用以下两种方法之一进行：

*   作为 XML 模式中的内联注释
*   作为传递给 JAXB 绑定编译器的外部文件中的语句

与[基本 JAXB 示例](basic.html)中的示例不同，后者侧重于各个 `Main.java` 类文件中的 Java 代码，此处的示例主要关注对 XML 架构**的定制**生成模式派生的 Java 绑定类。

* * *

**Note:** JAXB binding customizations currently must be made by hand. One of the goals of the JAXB technology is to standardize the format of binding declarations, thereby making it possible to create customization tools and to provide a standard interchange format between JAXB implementations.

* * *

本节介绍可以对 JAXB 绑定和验证方法进行的自定义。有关更多信息，请参阅 [JAXB 规范](http://jaxb.java.net)。

在大多数情况下，JAXB 绑定编译器生成的默认绑定就足够了。但是，有些情况下您可能希望修改默认绑定。其中一些包括：

*   为模式派生的 JAXB 包，类，方法和常量创建 API 文档：通过向模式添加自定义 Javadoc 工具注释，您可以解释特定于实现的概念，指南和规则。
*   为缺省 XML 名称到 Java 标识符映射无法自动处理的情况提供语义上有意义的自定义名称;例如：
    *   解决名称冲突（如 _JAXB 规范 _ 的附录 D.2.1 中所述）。请注意，JAXB 绑定编译器会检测并报告所有名称冲突。
    *   为非有效 Java 标识符的类型安全枚举常量提供名称;例如，枚举整数值。
    *   为绑定到 Java 属性或类的未命名模型组的 Java 表示提供更好的名称。
    *   提供比默认情况下从目标命名空间 URI 派生的更有意义的包名。
*   覆盖默认绑定;例如：
    *   指定必须将模型组绑定到类而不是列表。
    *   指定固定属性可以绑定到 Java 常量。
    *   将 XML Schema 内置数据类型的指定缺省绑定覆盖为 Java 数据类型。在某些情况下，您可能希望引入一个替代 Java 类，它可以表示内置 XML Schema 数据类型的其他特性。

## 自定义概述

本节介绍一些核心 JAXB 定制概念：

*   内联和外部自定义
*   范围，继承和优先级
*   自定义语法
*   自定义命名空间前缀

## 内联和外部自定义

默认 JAXB 绑定的自定义以**绑定声明**的形式传递给 JAXB 绑定编译器。这些绑定声明可以通过以下两种方式之一进行：

*   作为源 XML 模式中的内联注释
*   作为外部绑定自定义文件中的声明

对于某些人来说，使用内联自定义更容易，因为您可以在应用它们的架构的上下文中查看自定义。相反，使用外部绑定自定义文件可以自定义 JAXB 绑定而无需修改源模式，并使您可以轻松地将自定义应用于多个模式文件。

* * *

**Note:** You can combine the two types of customizations. For example, you could include a reference to an external binding customizations file in an inline annotation. However, you cannot declare both an inline and external customization on the same schema element.

* * *

以下各节将更详细地介绍这些类型的自定义中的每一种：

### 内联自定义

通过 XML 模式文件中的内联**绑定声明**进行的 JAXB 绑定的自定义采用`&lt; xsd：appinfo&gt;的形式。嵌入在模式`&lt; xsd：annotation&gt;中的`元素`元素（ `xsd：`是 XML 模式名称空间前缀，如 W3C _XML 模式第 1 部分：结构 _ 中所定义）。以下示例显示了内联自定义的一般形式：

```
<xs:annotation>
    <xs:appinfo>
        <!--
        ...
        binding declarations     .
        ...
        -->
    </xs:appinfo>
</xs:annotation>

```

自定义应用于在架构中声明它们的位置。例如，特定元素级别的声明仅适用于该元素。请注意，XML 架构名称空间前缀必须与`&lt; annotation&gt;一起使用。` 和`&lt; appinfo&gt;` 声明标签。在前面的示例中， `xs：`用作命名空间前缀，因此声明被标记为`&lt; xs：annotation&gt;` 和`&lt; xs：appinfo&gt;` 。

### 外部绑定自定义文件

通过使用包含绑定声明的外部文件对 JAXB 绑定进行自定义，采用以下示例中显示的一般形式：

```
<jxb:bindings schemaLocation = "xs:anyURI">
    <jxb:bindings node = "xs:string">*
        <!-- binding declaration -->
    <jxb:bindings>
</jxb:bindings>

```

*   `schemaLocation` 是对远程模式的 URI 引用。
*   `节点`是一个 XPath 1.0 表达式，用于标识与给定绑定声明关联的 `schemaLocation` 中的模式节点。

例如，JAXB 绑定声明文件中的第一个 `schemaLocation` / `节点`声明指定了模式名称和根模式节点：

```
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">
</jxb:bindings>

```

随后的 `schemaLocation` / `节点`声明，例如前一个模式示例中名为 `ZipCodeType` 的 `simpleType` 元素，采用以下形式：

```
<jxb:bindings node="//xs:simpleType [@name=’ZipCodeType’]">

```

### 绑定自定义文件格式

绑定自定义文件必须是 ASCII 文本。名称或扩展名无关紧要;虽然本章中使用的典型扩展是 `.xjb` 。

### 将自定义文件传递给 JAXB 绑定编译器

包含绑定声明的自定义文件使用以下语法传递给 JAXB 绑定编译器 `xjc` ：

```
xjc -b file schema

```

其中 _ 文件 _ 是绑定自定义文件的名称，_ 模式 _ 是您要传递给绑定编译器的模式的名称。

您可以拥有一个包含多个模式自定义的绑定文件，也可以将自定义分隔为多个绑定文件;例如：

```
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

```

请注意，命令行上的模式文件和绑定文件的顺序无关紧要;虽然每个绑定自定义文件必须在命令行上有自己的 `-b` 开关。

有关 `xjc` 编译器选项的更多信息，请参阅 [JAXB 编译器选项](examples.html#bnbal)。

### 外部绑定自定义的限制

有几个规则适用于在外部绑定自定义文件中进行的绑定声明，这些规则不适用于在源模式中内联的类似声明：

*   绑定自定义文件必须以 `jxb：bindings version` 属性开头，加上 JAXB 和 XMLSchema 名称空间的属性：

    ```
    &lt;jxb:bindings version="1.0" 
        xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;

    ```

*   必须使用 `jxb：bindings` 声明指定 `schemaLocation` 和 `node` 属性，以 XPath 表示法显式标识绑定声明所适用的远程模式：
    *   `schemaLocation` 指定对远程模式的 URI 引用。
    *   `节点`指定 XPath 1.0 表达式，该表达式标识与给定绑定声明关联的 `schemaLocation` 中的模式节点;在绑定自定义文件中的初始 `jxb：bindings` 声明的情况下，该节点通常是`“/ xs：schema”`。

同样，必须使用 XPath 表示法指定要应用自定义的模式中的各个节点;例如：

```
<jxb:bindings node="//xs:complexType [@name=’USAddress’]">

```

在这种情况下，绑定编译器将自定义应用于节点，就好像声明嵌入在节点的`&lt; xs：appinfo&gt;中一样。` 元素。

总结这些规则，外部绑定元素`&lt; jxb：bindings&gt;` 仅在以下三种情况下由 JAXB 绑定编译器进行处理：

*   当其父级是`&lt; xs：appinfo&gt;` 元素。
*   当它是另一个`&lt; jxb：bindings&gt;的祖先时`元素。
*   当它是文档的根元素时。具有`&lt; jxb：bindings&gt;的 XML 文档`元素作为其根被称为外部绑定声明文件。

### 范围，继承和优先顺序

可以在四个不同级别或**范围**上自定义或覆盖默认 JAXB 绑定。

下图说明了自定义声明的继承和优先级。具体来说，金字塔顶部的声明继承并取代它们下面的声明。

组件声明继承自和取代定义声明;定义声明继承并取代 Schema 声明;和 Schema 声明继承并取代全局声明。

图：自定义范围继承和优先级

<center>![Customization Scope Inheritance and Precedence](img/48a3f882f7c84c81cd2fdbce1579f19a.jpg)</center>

### 自定义语法

以下部分介绍了四种类型的 JAXB 绑定声明的语法，XML-to-Java 数据类型绑定声明的语法以及自定义命名空间前缀。

*   [全球约束声明](#bnbbr)
*   [架构绑定声明](#bnbbs)
*   [类绑定声明](#bnbbt)
*   [属性绑定声明](#bnbbu)
*   [javaType 绑定声明](#bnbbv)
*   [Typesafe 枚举绑定声明](#bnbbw)
*   [javadoc 绑定声明](#bnbbx)

### 全球约束声明

使用`&lt; globalBindings&gt;声明全局范围自定义。` 。全局范围自定义的语法如下：

```
<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` 可以是`索引`或任何实现 `java.util.List` 的完全限定类名。
*   `fixedAttributeAsConstantProperty` 可以是 `true` ， `false` ， `1` 或 `0` 。默认值为 `false` 。
*   `generateIsSetMethod` 可以是`真`，`假`， `1` 或 `0` 。默认值为 `false` 。
*   `enableFailFastCheck` 可以是 `true` ， `false` ， `1` 或 `0` 。如果 `enableFailFastCheck` 为 `true` 或 `1` 并且 JAXB 实现支持此可选检查，则在设置属性时执行类型约束检查。默认值为 `false` 。请注意，JAXB 实现不支持 failfast 验证。
*   `choiceContentProperty` 可以是 `true` ， `false` ， `1` 或 `0` 。默认值为 `false` 。当 `bindingStyle` 是 `elementBinding` 时， `choiceContentProperty` 无关。因此，如果 `bindingStyle` 指定为 `elementBinding` ，则 `choiceContentProperty` 必须导致无效的自定义。
*   `underscoreBinding` 可以是 `asWordSeparator` 或 `asCharInWord` 。默认值为 `asWordSeparator` 。
*   `typesafeEnumBase` 可以是 QNames 列表，每个 QNames 必须解析为简单的类型定义。默认值为 `xs：NCName` 。有关 `simpleType` 定义到 Java `typesafe enum` 类的本地化映射的信息，请参阅 [Typesafe 枚举绑定声明](#bnbbw)。
*   `typesafeEnumMemberName` 可以是 `generateError` 或 `generateName` 。默认值为 `generateError` 。
*   `enableJavaNamingConventions` 可以是 `true` ， `false` ， `1` 或 `0` 。默认值为 `true` 。
*   `bindingStyle` 可以是 `elementBinding` ，也可以是 `modelGroupBinding` 。默认值为 `elementBinding` 。
*   `&lt; javaType&gt;` 可以是零个或多个 javaType 绑定声明。有关更多信息，请参阅 [javaType 绑定声明](#bnbbv)。

`&lt; globalBindings&gt;` 声明仅在顶级`模式`元素的`注释`元素中有效。只能存在`&lt; globalBindings&gt;的单个实例。任何给定模式或绑定声明文件中的`声明。如果一个源模式包含或导入第二个源模式，则`&lt; globalBindings&gt;必须在第一个源模式中声明`声明。

### 架构绑定声明

使用`&lt; schemaBindings&gt;声明模式范围自定义。` 。架构范围自定义的语法是：

```
<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>

```

如上所示，`&lt; schemaBinding&gt;` 声明包括两个子组件：

*   `&lt; package&gt; ...&lt; / package&gt;` 指定包的名称，如果需要，还指定模式派生类的 API 文档的位置。
*   `&lt; nameXmlTransform&gt; ...&lt; / nameXmlTransform&gt;` 指定要应用的自定义。

### 类绑定声明

`&lt; class&gt;` 绑定声明使您可以自定义架构元素与 Java 内容接口或 Java `元素`接口的绑定。 `&lt; class&gt;` 声明可用于自定义：

*   模式派生 Java 接口的名称
*   模式派生的 Java 内容接口的实现类

`&lt; class&gt;的语法`自定义是：

```
<class 
    [ name = "className"]
    [ implClass= "implClass" ] >
    [ <javadoc> ... </javadoc> ]
</class>

```

*   `name` 是派生 Java 接口的名称。它必须是有效的 Java 接口名称，并且不得包含包前缀。包前缀继承自包的当前值。
*   `implClass` 是 _className_ 的实现类的名称，必须包含完整的包名。
*   `&lt; javadoc&gt;` 元素为模式派生的 Java 接口指定 Javadoc 工具注释。在此输入的字符串必须使用 `CDATA` 或`&lt;` 来逃避嵌入式 HTML 标签。

### 属性绑定声明

`&lt; property&gt;` 绑定声明使您可以自定义 XML 模式元素与其 Java 表示的绑定作为属性。定制的范围可以是定义级别或组件级别，这取决于`&lt; property&gt;的位置。指定了`绑定声明。

`&lt; property&gt;的语法`自定义是：

```
<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>

```

*   `名称`定义自定义值 `propertyName` ;它必须是有效的 Java 标识符。
*   `collectionType` 定义自定义值 `propertyCollectionType` ，它是属性 `propertyCollectionType` 的集合类型。如果指定，该属性可以是`索引`或任何实现 `java.util.List` 的完全限定类名。
*   `fixedAttributeAsConstantProperty` 定义自定义值 `fixedAttributeAsConstantProperty` 。该值可以是`真`，`假`， `1` 或 `0` 。
*   `generateIsSetMethod` 定义 `generateIsSetMethod` 的自定义值。该值可以是`真`，`假`， `1` 或 `0` 。
*   `enableFailFastCheck` 定义自定义值 `enableFailFastCheck` 。该值可以是`真`，`假`， `1` 或 `0` 。请注意，JAXB 实现不支持 failfast 验证。
*   `&lt; javadoc&gt;` 为属性的 getter 方法自定义 Javadoc 工具注释。

### javaType 绑定声明

`&lt; javaType&gt;` 声明提供了一种自定义 XML 数据类型与 Java 数据类型之间的转换的方法。 XML 提供的数据类型比 Java 多，因此`&lt; javaType&gt;` 声明使您可以在默认 JAXB 绑定无法充分表示架构时指定自定义数据类型绑定。

目标 Java 数据类型可以是 Java 内置数据类型或特定于应用程序的 Java 数据类型。如果将特定于应用程序的 Java 数据类型用作目标，则您的实现还必须提供用于解组和编组数据的解析和打印方法。为此，JAXB 规范支持 `parseMethod` 和 `printMethod` ：

*   在解组期间调用 `parseMethod` 以将输入文档中的字符串转换为目标 Java 数据类型的值。
*   在编组期间调用 `printMethod` 以将目标类型的值转换为词法表示。

如果您更喜欢定义自己的数据类型转换，JAXB 定义了一个静态类 `DatatypeConverter` ，以帮助解析和打印 XML Schema 内置数据类型的有效词法表示。

`&lt; javaType&gt;的语法`定制是：

```
<javaType name= "javaType"
    [ xmlType= "xmlType" ]
    [ hasNsContext = "true" | "false" ]
    [ parseMethod= "parseMethod" ]
    [ printMethod= "printMethod" ]>

```

*   `name` 是 `xmlType` 要绑定的 Java 数据类型。
*   `xmlType` 是 `javaType` 要绑定的 XML Schema 数据类型的名称;当`&lt; javaType&gt;的父级时，此属性是必需的。` 声明是`&lt; globalBindings&gt;` 。
*   `hasNsContext` 允许将命名空间上下文指定为 print 或 parse 方法的第二个参数;可以是`真`，`假`， `1` 或 `0` 。默认情况下，此属性为 `false` ，在大多数情况下，无需更改它。
*   `parseMethod` 是解组时要调用的解析方法的名称。
*   `printMethod` 是编组期间要调用的打印方法的名称。

`&lt; javaType&gt;` 声明可用于：

*   A `&lt; globalBindings&gt;` 声明
*   简单类型定义的注释元素， `GlobalBindings` 和`&lt; basetype&gt;` 声明
*   `&lt; property&gt;` 声明

有关`&lt; javaType&gt;的示例，请参阅 [`MyDatatypeConverter` 类](#bnbch)。` 声明和 `DatatypeConverterInterface` 接口在自定义数据类型转换器类中实现。

### Typesafe 枚举绑定声明

类型安全枚举声明提供了将 XML `simpleType` 元素映射到 Java `类型安全枚举`类的本地化方法。您可以使用两种类型的类型安全枚举声明：

*   `&lt; typesafeEnumClass&gt;` 允许您将整个 `simpleType` 类映射到 `typesafe enum` 类。
*   `&lt; typesafeEnumMember&gt;` 允许您将 `simpleType` 类的选定成员映射到 `typesafe enum` 类。

在这两种情况下，这种类型的定制有两个主要限制：

*   只能使用此绑定声明自定义具有枚举方面的 `simpleType` 定义。
*   此自定义一次仅适用于单个 `simpleType` 定义。要在全局级别上映射类似 `simpleType` 定义的集合，请使用`&lt; globalBindings&gt;中的 `typesafeEnumBase` 属性。` 声明，如[全局绑定声明](#bnbbr)中所述。

`&lt; typesafeEnumClass&gt;的语法`定制是：

```
<typesafeEnumClass 
    [ name = "enumClassName" ]
    [ <typesafeEnumMember> ... </typesafeEnumMember> ]*
    [ <javadoc> enumClassJavadoc </javadoc> ]
</typesafeEnumClass>

```

*   `名称`必须是有效的 Java 标识符，并且必须没有包前缀。
*   您可以拥有零个或多个`&lt; typesafeEnumMember&gt;嵌入在`&lt; typesafeEnumClass&gt;中的`声明`声明。
*   `&lt; javadoc&gt;` 自定义枚举类的 Javadoc 工具注释。

`&lt; typesafeEnumMember&gt;的语法`定制是：

```
<typesafeEnumMember 
    name = "enumMemberName">
    [ value = "enumMemberValue" ]
    [ <javadoc> enumMemberJavadoc </javadoc> ]
</typesafeEnumMember>

```

*   必须始终指定`名称`，并且必须是有效的 Java 标识符。
*   `值`必须是源模式中指定的枚举值。
*   `&lt; javadoc&gt;` 为枚举常量自定义 Javadoc 工具注释。

对于内联注释，`&lt; typesafeEnumClass&gt;必须在`&lt; simpleType&gt;的注释元素中指定`声明。` 元素。 `&lt; typesafeEnumMember&gt;必须在枚举成员的注释元素中指定`。这使得枚举成员可以独立于枚举类进行定制。

有关类型安全枚举设计模式的信息，请参阅 Oracle 技术网上 Joshua Bloch _ 有效 Java 编程 _ 的[示例章节。](http://www.oracle.com/technetwork/java/page1-139488.html) 。

### javadoc 绑定声明

`&lt; javadoc&gt;` 声明允许您向模式派生的 JAXB 包，类，接口，方法和字段添加自定义 Javadoc 工具注释。注意`&lt; javadoc&gt;` 声明不能全局应用;它们仅作为其他绑定自定义的子元素有效。

`&lt; javadoc&gt;的语法`定制是：

```
<javadoc>
    Contents in <b>Javadoc<\b> format.
</javadoc>

```

要么

```
<javadoc>
    <<![CDATA[Contents in <b>Javadoc<\b> format ]]>
</javadoc>

```

请注意`&lt; javadoc&gt;中的文档字符串。在包级别应用的`声明必须包含`&lt; body&gt;` 开启和关闭标签;例如：

```
<jxb:package 
    name="primer.myPo">
    <jxb:javadoc>
        <![CDATA[<body>
            Package level documentation for generated package primer.myPo.
        </body>]]>
    </jxb:javadoc>
</jxb:package>

```

### 自定义命名空间前缀

所有标准 JAXB 绑定声明必须以一个映射到 JAXB 名称空间 URI [http://java.sun.com/xml/ns/jaxb](http://java.sun.com/xml/ns/jaxb) 的名称空间前缀开头。例如，在该样本中，使用 `jxb：`。为此，您希望使用标准 JAXB 绑定声明**自定义的任何模式必须**在模式文件的顶部包含 JAXB 名称空间声明和 JAXB 版本号。例如，在 `po.xsd` 中的 Customize Inline 示例中，名称空间声明如下：

```
<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` 声明分别用于指定全局范围和架构范围自定义。这些自定义范围在[范围，继承和优先级](#bnbbo)中有更详细的描述。

#### 自定义内联示例

Customize Inline 示例说明了通过内联注释对名为 `po.xsd` 的 XML 模式进行的一些基本自定义。此外，此示例实现了一个自定义数据类型转换器类 `MyDatatypeConverter.java` ，它说明了`&lt; javaType&gt;中的打印和解析方法。` 自定义处理自定义数据类型转换。

总结一下这个例子：

1.  `po.xsd` 是一个包含内联绑定自定义的 XML 模式。
2.  `MyDatatypeConverter.java` 是一个 Java 类文件，它实现`&lt; javaType&gt;指定的打印和解析方法。 `po.xsd` 中的`自定义。
3.  `Main.java` 是 Customize Inline 示例中的主类文件，它使用 JAXB 编译器生成的模式派生类。

### 使用 Ant 构建并运行自定义内联示例

要使用 Ant 编译和运行 Customize Inline 示例，请在终端窗口中转到 _jaxb-ri-install_ `/ samples / inline-customize /` 目录并键入以下内容：

```
ant 

```

本示例中的关键自定义和自定义 `MyDatatypeConverter.java` 类将在下一节中详细介绍。

### 自定义架构

Customize Inline 示例中使用的自定义架构位于文件 _jaxb-ri-install_ `/samples/inline-customize/po.xsd` 中。自定义位于`&lt; xsd：annotation&gt;` 标签。

### 全球约束声明

以下代码示例显示 `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 常量。默认情况下，固定属性将映射到简单属性或集合属性，以较合适的方式。
*   将 `collectionType` 设置为 `java.util.Vector` 指定生成的实现类中的所有列表在内部表示为向量。请注意，为 `collectionType` 指定的类名必须实现 `java.util.List` ，并且可由 `newInstance` 调用。
*   如果 `typesafeEnumBase` 设置为 `xsd：string` ，则它是一种全局方式，用于指定直接或间接从 `xsd：string 派生的所有`简单`类型定义`并且具有枚举方面，必须默认绑定到`类型安全枚举`。如果 `typesafeEnumBase` 设置为空字符串（`“”`），则默认情况下`简单`类型定义不会绑定到`类型安全枚举`类。 `typesafeEnumBase` 的值可以是除 `xsd：boolean` 和两种二进制类型之外的任何原子简单类型定义。
*   JAXB 实现不支持 `enableFailFastCheck` 属性。

    * * *

    **注意：**使用 typesafe enum 类可以将模式枚举值映射到 Java 常量，这样就可以对 Java 常量而不是字符串值进行比较。

    * * *

### 架构绑定声明

以下代码显示 `po.xsd` 中的模式绑定声明：

```
<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>

```

*   `&lt; jxb：package name =“primer.myPo”/&gt;` 指定 `primer.myPo` 作为生成模式派生类的包。
*   `&lt; jxb：nameXmlTransform&gt;` 指定默认情况下所有生成的 Java 元素接口都将 `Element` 附加到生成的名称。例如，当针对此模式运行 JAXB 编译器时，将生成元素接口 `CommentElement` 和 `PurchaseOrderElement` 。相比之下，如果没有这种自定义，默认绑定会生成 `Comment` 和 `PurchaseOrder` 。如果架构在不同的符号空间中使用相同的名称，则此自定义很有用;例如，在全局元素和类型定义中。在这种情况下，此自定义使您可以使用一个声明来解决冲突，而不必使用单独的绑定声明单独解决每个冲突。
*   `&lt; jxb：javadoc&gt;` 为 `primer.myPo` 包指定了自定义的 Javadoc 工具注释。注意，与`&lt; javadoc&gt;不同。` 类级别的声明，如下例所示，开启和关闭`&lt; body&gt; `&lt; javadoc&gt;时必须包含`标签。` 声明是在包级别进行的。

### 类绑定声明

以下代码显示 `po.xsd` 中的类绑定声明：

```
<xsd:complexType name="PurchaseOrderType">
    <xsd:annotation>
        <xsd:appinfo>
            <jxb:class name="POType">
                <jxb:javadoc>
                    A &lt;b>Purchase Order&lt;/b>
                    consists of addresses and items.
                </jxb:javadoc>
            </jxb:class>
        </xsd:appinfo>
    </xsd:annotation>
    <!-- ... -->
</xsd:complexType>

```

模式派生 `POType` 类的 Javadoc 工具注释将包含描述`“A&amp; lt; b&gt; Purchase Order&amp; lt; / b&gt;由地址和项目组成。”` `&amp; lt;` 用于逃离`&lt; b&gt;上的开口支架。` HTML 标签。

* * *

**Note:** When a `<class>` customization is specified in the `appinfo` element of a `complexType` definition, as shown in the previous example, the `complexType` definition is bound to a Java content interface.

* * *

后来在 `po.xsd` 中，另一个`&lt; javadoc&gt;` 自定义在此类级别声明，但这次使用 `CDATA` 转义 HTML 字符串：

```
<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:** If you want to include HTML tags in a `<jaxb:javadoc>` customization, you must enclose the data within a `CDATA` section or escape all left angle brackets using `&lt;`. See [XML 1.0 2nd Edition](http://www.w3.org/TR/2000/REC-xml-20001006#sec-cdata-sect) for more information.

* * *

### 属性绑定声明

这里特别感兴趣的是 `generateIsSetMethod` 定制，它会导致生成另外两个属性方法 `isSetQuantity` 和 `unsetQuantity` 。这些方法使客户端应用程序能够区分模式默认值和实例文档中显式发生的值。

例如，在 `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` 适用于`数量`元素，该元素绑定到 `Items.ItemType` 接口中的属性。 `unsetQuantity` 和 `isSetQuantity` 方法在 `Items.ItemType` 接口中生成。

### `MyDatatypeConverter` Class

类 _jaxb-ri-install_ `/ samples / inline-customize / src / inlinecustomize / primer / MyDatatypeConverter` ，如下例所示，提供了一种自定义 XML 数据转换的方法使用`&lt; javaType&gt;的 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);
    }
};

```

以下代码显示了如何在`&lt; javaType&gt;中引用 `MyDatatypeConverter` 类。 `po.xsd` 中的`声明：

```
<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` 。另请注意，因为`&lt; jxb：javaType name =“int”/&gt;` 在 `ZipCodeType` 中声明，自定义适用于引用此 `simpleType` 定义的所有 JAXB 属性，包括 `getZip` 和 `setZip` 方法。

#### DataType 转换器示例

DataType Converter 示例类似于 Customize Inline 示例。与 Customize Inline 示例一样，数据类型转换器示例中的自定义是通过在应用程序的 XML 模式中使用内联绑定声明来实现的， `po.xsd` 。

Customize Inline 和 DataType Converter 示例的全局，模式和包以及大多数类自定义都是相同的。数据类型转换器示例与 Customize Inline 示例的不同之处在于 `parseMethod` 和 `printMethod` ，用于将 XML 数据转换为 Java `int` 数据类型。

具体而言，数据类型转换器示例使用 `javax.xml.bind.DatatypeConverter` 提供的内置方法，而不是使用自定义 `MyDataTypeConverter` 类中的方法来执行这些数据类型转换：

```
<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 版本，命名空间和架构属性](#bnbcm)
*   [全局和架构绑定声明](#bnbcq)
*   [类声明](#bnbcr)

### JAXB 版本，命名空间和架构属性

所有 JAXB 绑定声明文件必须以：

*   JAXB 版本号
*   命名空间声明
*   架构名称和节点

`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 版本号

根元素为`&lt; jaxb：bindings&gt;的 XML 文件`被视为外部绑定文件。根元素必须指定其绑定声明必须符合的 JAXB 版本属性;特别是根`&lt; jxb：bindings&gt;` 元素必须包含&lt; `jxb：版本&gt;` 声明或`版本`属性。相反，在内联绑定声明时，JAXB 版本号作为`&lt; xsd：schema&gt;的属性。` 声明：

```
<xsd:schema 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
    jxb:version="1.0">

```

### 命名空间声明

如 [JAXB 版本，命名空间和架构属性](#bnbcm)所示，外部绑定声明文件中的命名空间声明包括 JAXB 命名空间和 XMLSchema 命名空间。请注意，此示例中使用的前缀实际上可能是您想要的任何内容;重要的是始终在文件的后续声明中使用您在此处定义的任何前缀。

### 架构名称和架构节点

[JAXB 版本，命名空间和架构属性](#bnbcm)中代码的第四行指定此绑定声明文件应用于的架构的名称，以及自定义将首先生效的架构节点。此文件中的后续绑定声明可以引用模式中的特定节点，但是第一个声明应该包含整个模式;例如，在 `bindings.xjb` 中：

```
<jxb:bindings schemaLocation="po.xsd" node="/xs:schema">

```

### 全局和架构绑定声明

`bindings.xjb` 中的全局模式绑定声明与 DataType Converter 示例中 `po.xsd` 中的相同。唯一的区别是因为 `po.xsd` 中的声明是内联的，你必须将它们嵌入`&lt; xs：appinfo&gt;` 元素，它们又嵌入`&lt; xs：annotation&gt;` 元素。在外部绑定文件中不需要以这种方式嵌入声明。

```
<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>

```

### 类声明

`bindings.xjb` 中的类级绑定声明与 `po.xsd` 中的数据类型转换器示例中的类似声明有两种不同：

*   与 `bindings.xjb` 中的所有其他绑定声明一样，您无需在架构`&lt; xsd：appinfo&gt;中嵌入自定义项。` 元素。
*   您必须指定要应用自定义的架构节点。此类声明的一般语法是：

    ```
    &lt; jxb：bindings node =“//  node-type  [@ name =' node-name ' ]“&GT; 
    ```

例如，以下代码显示名为 `USAddress` 的 `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` 是子元素`名称`和 `zip` 的父亲，因此`&lt; / jxb：bindings&gt;` 标签包含子元素和类级别 `javadoc` 声明的`绑定`声明。

#### 外部自定义示例

外部自定义示例与 DataType Converter 示例相同，只是外部自定义示例中的绑定声明是使用外部绑定声明文件而不是源 XML 架构中的内联进行的。

外部自定义示例中使用的绑定自定义文件是 _jaxb-ri-install_ `/samples/external-customize/binding.xjb` 。

本节将 `bindings.xjb` 中的自定义声明与数据类型转换器示例中 XML 模式 `po.xsd` 中使用的类似声明进行比较。这两组声明实现了完全相同的结果。

### 使用 Ant 构建并运行外部自定义示例

要使用 Ant 编译和运行外部自定义示例，请在终端窗口中转到 _jaxb-ri-install_ `/ samples / external-customize /` 目录并键入以下内容：

```
ant

```