JiBX 1.2,第 2 部分: 从 XML 模式到 Java 代码,通过 XML 模式生成更干净的自定义 Java 代码

JiBx开发入门指南 JiBx又一个不错的xml绑定工具,和jaxb等一样,都是属于xml绑定工具。而JiBx使用java字节码enhance技术,不像jaxb等更多在于源代码生成技术。JiB的工作主要在于前期,也就是进行字节码绑定,这一部分基本上都是在编译器完成的。在运行期,不需要任何的配置,由于字节码已经嵌入java类中,并不是在于运行期绑定,而是通过元数据或者xsd文件进行解析绑定。效率和性能上无疑是佼佼者。 文档格式:PDF(清晰),语言:中文 立即下载

安装 JiBX

在继续学习本教程之前,您需要先安装 JiBX。下载 最新的 1.2.x 发行版 ZIP 并将其解压缩到系统中便于访问的位置。您将得到名为 jibx 的目录,其中包含所有的 JiBX JAR、文档、示例,甚至源代码。

安装教程代码

现在下载教程 样例代码,也是以 ZIP 文件的形式提供的。在系统中安装样例代码的最简单方法是在 JiBX 安装的根目录中解压缩 ZIP(或者对于 Windows®,将 dwcode2 目录从 ZIP 文件中复制到 JiBX 安装的根目录中)。此操作应当在 jibx 目录中创建 dwcode2 子目录,而且 dwcode2 子目录中包含示例文件(包括 build.xml、custom.xml 和其他文件)。

样例代码包括自动运行 JiBX 工具并处理示例涉及的其他步骤的 Ant 构建文件。如果直接将样例代码安装到 JiBX 安装目录中,则构建可以访问 JiBX JAR 而无需任何附加配置。如果在其他位置安装样例代码,则仍然可以使用 Ant 构建。在这种情况下,您只需编辑样例代码目录中的 build.properties 文件,然后将 jibx-home 属性的值改为 JiBX 安装路径。

通过模式生成默认绑定和代码

通过 XML 模式定义生成 JiBX 绑定定义及相应的 Java 代码十分简单。您将在本节中了解具体操作。

简单示例模式简介

我将使用 第 1 部分 中生成的一个模式作为一个简单示例。清单 1 显示了该模式的简短版本,用于表示在线商店的订单。样例代码的 dwcode2 目录中的 starter.xsd 提供了完整的模式。


清单 1. 第一个示例模式

生成默认绑定和代码

要通过 XML 模式生成 JiBX 绑定和 Java 类,您只需运行 JiBX 发行版中的 jibx-tools.jar 附带的 org.jibx.schema.codegen.CodeGen 工具。您可以通过命令行直接运行该工具,也可以通过 Apache Ant 之类的构建工具间接运行该工具。

本教程的下载部分包括 Ant build.xml 脚本,其中 codegen 目标用于运行生成。

要尝试使用此脚本,请打开已安装下载的 dwcode2 目录中的控制台,然后输入 ant codegen。如果系统中安装了 Ant 并且根据说明安装了下载代码,则应当会看到类似图 1 所示的输出:


图 1. 使用 Ant 构建

您还可以直接从控制台运行 CodeGen。为此,您需要:

  1. 在 Java 类路径中包括 jibx-tools.jar。
  2. 指定 org.jibx.schema.codegen.CodeGen 为要运行的类。
  3. 列出要生成的模式定义。

提供的 Ant codegen 目标将使用几个附加参数告诉 CodeGen 使用 gen/src 目录作为生成的数据模型包结构的根目录,并且在运行生成前删除该目录中的所有现有文件。下面是用于从 dwcode2 目录的控制台中复制 Ant codegen 目标的 Java 命令行(假定您遵循了推荐安装说明):

java -cp ../lib/jibx-tools.jar org.jibx.schema.codegen.CodeGen -t gen/src -w starter.xsd

对于 Windows,该命令为:

java -cp ../lib/jibx-tools.jar org.jibx.schema.codegen.CodeGen -t gen/src -w starter.xsd

您可以通过命令行向 CodeGen 传递许多其他选项。您稍后将在教程中看到这些选项。现在,让我们看一看生成的 Java 代码。

生成的工件

生成的代码由五个类组成,分别对应于 清单 1 模式中的五个全局类型定义。清单 2 显示了生成的代码的一些样例,其中包括 org.jibx.starter.Order 类的摘录及整个 org.jibx.starter.Shipping 类:


清单 2. 生成的代码

通过 清单 2 可以看到,CodeGen 在生成的代码中将模式文档自动转换为 Javadoc(在此处显示为每个类 Javadoc 中的前导注释,以及显示为 getShipTo() 和 setShipTo() 方法的注释部分)。默认情况下,CodeGen 还合并类 Javadoc 中的实际模式定义,而对于 get/set 属性访问方法,它将描述与属性对应的模式组件。

对于重复值,例如清单 1 订单 complexType 定义中的重复项目元素,CodeGen 将默认生成 Java 5 类型的列表。对于 simpleType 限制枚举,例如清单 1 中的送货类型,CodeGen 将默认生成 Java 5 枚举类型。清单 2 中显示了为这两个实例生成的代码。

生成的 JiBX 绑定

除了生成的代码之外,CodeGen 还将产生 JiBX 绑定定义(在本例中为 binding.xml 文件),该绑定定义将告诉 JiBX 绑定编译器如何在 Java 类与 XML 之间进行转换。绑定定义包含 JiBX 所完成的转换的完整信息,因此它们必然非常复杂。幸运的是,使用 CodeGen 绑定和代码生成,您无需了解绑定定义即可使用 JiBX,因此本教程不会介绍这部分的详细信息。

处理 XML 文档

在本节中,您将了解如何在运行时运行 JiBX 绑定编译器和使用 JiBX,从而处理 XML 文档。

运行 JiBX 绑定编译器

要在处理 XML 文档时使用生成的绑定定义,首先需要运行 JiBX 绑定编译器。按照绑定定义的指定,绑定编译器将把字节码添加到编译后的类文件,这些文件实际实现了与 XML 之间的来回转换。每次重新编译 Java 类或修改绑定定义时,都必须运行绑定编译器,因此一般最好把绑定编译器步骤添加到项目的标准构建流程中。

jibx-bind.jar 中的 JiBX 发行版附带了绑定编译器。JiBX 文档将提供通过各种方法运行绑定编译器的完整信息,包括如何在运行应用程序时(而非在构建时)调用绑定编译器。JiBX 还提供了 Eclipse 和 IntelliJ IDEA 的插件,这样在使用这些 IDE 时将自动运行绑定编译器。

根据本教程的目的,您将把一切简单化并且只通过 Ant 运行绑定编译器。build.xml 的 compile 目标将通过编译生成的代码和提供的测试程序来为绑定做准备,而 bind 目标实际运行绑定编译器。假定您已经运行了 codegen 目标,图 2 将显示运行这些目标时应当会看到的输出(您还可以通过在命令行中按顺序列出这些目标来运行全部三个目标:ant codegen compile bind)。


图 2. Ant 构建 compile 和 bind 任务

在运行时使用 JiBX

清单 3 显示了匹配模式的简单测试文档,包含在教程的代码下载中,名为 starter.xml:


清单 3. 订单模式的测试文档

下载包还包括一个简单测试程序,它在本文中显示为清单 4,用于演示如何使用 JiBX 解组 及编组 文档。编组是在内存中生成对象的 XML 表示的过程,可能包括从初始对象链接的对象;解组是编组的反向过程,它将通过 XML 表示在内存中构建一个对象(还有可能是一些链接的对象)。Ant run 目标将执行此测试程序,使用 清单 3 文档作为输入并把编组后的文档副本写到名为 out.xml 的文件中。


清单 4. 测试程序

图 3 显示了运行 run 目标时应当会看到的输出:


图 3. Ant 构建 run 任务

这是 第 1 部分 中使用的同一个测试程序,并且同样具有第一部分教程中讨论的限制。就像在第 1 部分中一样,out.xml 文件包含了将解组原始文档获得的订单数据重新编组后生成的输出。

CodeGen 自定义简介

在本节中,您将了解自定义 CodeGen 以控制通过简单模式生成的代码结构的基础知识。

简单自定义示例

CodeGen 支持在代码和绑定生成的许多方面进行丰富的自定义。要应用的自定义集将作为 XML 文档传递给 CodeGen,其中包括与模式或模式组件相关的嵌套元素。清单 5 给出了一个简单示例:


清单 5. 简单自定义示例

					
<schema prefer-inline="true" show-schema="false" enumeration-type="simple"
  generate-all="false" includes="order item"/>

清单 5 自定义包含单个无名称空间的模式元素,以及针对特定自定义的几个不同属性(到目前为止,您只是在使用单个模式定义,因此可以使用这种非常简单的自定义形式。稍后在本教程中,您将看到使用多个模式的自定义示例)。第一个自定义属性 — prefer-inline="true" — 将告诉 CodeGen 内联只引用一次的模式定义,而不是执行将其保留为单独类的默认行为。第二个属性 — show-schema="false" — 将阻止在类 Javadoc 中嵌入模式定义。enumeration-type="simple" 将生成简单的类型安全枚举而非 Java 5 枚举。

最后一对属性将一起工作。默认情况下,CodeGen 将为指定为输入的模式中的每个全局类型定义都生成一个单独的顶级类,并且在为每个 complexType 生成的 JiBX 绑定中生成对应的抽象映射。generate-all="false" 属性将更改这种默认行为,只显式地生成特别包括的或引用自 included 类型的那些 complexType。随后,includes="order item" 属性将给出要生成的名称,选择这些名称以保持与测试程序的兼容性 — 需要 <order> 元素,原因是它是实例文档的根元素,并且需要 complexType 项,因为测试程序期望在计算订单总数时找到此类型的独立顶级类。

通过使用 Ant custgen 任务而非 codegen 任务(或者只使用 full 任务,该任务将运行完整的 clean custgen compile bind run 目标序列),您可以尝试这些自定义。清单 6 显示了生成的代码片段,您可以将其与 清单 2 所示的默认生成的代码相比较。除了简化的类 Javadoc 之外,最大的差别是 Customer 类现在是内联的,而 Shipping 类现在是使用自定义的类型安全枚举类的内部类。


清单 6. 用自定义生成的代码

还有许多其他的自定义也可用于 CodeGen。您稍后将在本教程中看到这些自定义的一些示例,但是为了更好地说明这些自定义的强大之处,有必要继续介绍一个更复杂的模式。

尝试一个实际的模式

独立的模式定义非常适合用于简单演示,但是在应用到企业应用程序中广泛使用的复杂模式定义时,它无法让用户了解工具的工作原理。现在将以一个符合行业标准的 HR-XML 模式定义为例,继续介绍一个更实际的示例。

HR-XML TimeCard 模式

HR-XML Consortium 是为开发针对人力资源的 XML 表示的开放标准而成立的组织。它代表着 110 多家企业成员,并且几乎有 50 家技术公司通过了符合其标准的认证。

本教程中使用的 HR-XML 模式包含 157 个模式,其中混合了顶级文档定义和常用组件。CodeGen 可以轻松地处理这些模式,但是生成的类数目和相互关系的复杂度掩盖了模式处理的更有趣方面。为了关注这些细节,这里使用的 HR-XML 的子集包括 TimeCard 元素的一个顶级文档定义,以及作为 TimeCard 定义的一部分引用的常用组件 — 总计七个模式定义。

您可以在 hrxml/schemas 目录下找到本教程中使用的 HR-XML 模式定义子集。清单 7 显示了经过编辑的 TimeCard 元素定义的主要模式。这将给出一个 HR-XML 模式样式样例,该样例将同时使用嵌套及全局类型的定义,并且比第一个示例包含更广泛的模式结构,包括:

  • <xs:choice> 组合器(compositor)(如 TimeCardType 定义中的某些嵌入式 complexType 所示)
  • <xs:any> 粒子(particle)(查看清单开始部分的 AdditionalDataType 定义)
  • <xs:simpleType> <union>(查看清单末尾的 TimeCardDuration 定义)
  • 非枚举型 <xs:simpleType> 限制


清单 7. HR-XML TimeCard 模式

为 TimeCard 生成的代码

hrxml 目录中的 Ant build.xml 文件将定义尝试为 TimeCard 模式生成基本代码的 Ant 目标,包括默认生成和几个自定义示例(稍后讨论)。样例目录还包含一个测试程序 org.jibx.hrxml.Test。它将使用生成的数据模型类将样例文档解组,然后将文档重新编组并将结果与原始文档相比较。并且样例目录中有一组来自 HR-XML 发行版的测试文档。codegen 目标将使用默认值运行 CodeGen,compile 将编译生成的代码和测试代码,bind 将编译 JiBX 绑定,而 roundtrip 将对样例文档运行测试程序。您还可以使用 full 任务按顺序运行所有这些步骤。

大多数通过模式生成代码的方式都将为每个 complexType 定义及枚举 simpleType 生成一个单独的类。通过在可能的位置检查引用和内联定义,并且忽略包括和导入的模式定义中未使用的定义,CodeGen 通常能够减少生成的类的数量。在 TimeCard 模式中,有总计 10 个全局(命名的)complexType 和附加的 23 个本地(匿名)complexType,以及 8 个枚举 simpleType。生成的默认数据模型将包含 15 个顶级类和 23 个内部类,要比根据模式组件计算的少一些。您稍后将看到,如果不需要用到全部模式组件,如何使用自定义进一步简化数据模型。

<xs:choice> 处理

清单 8 显示了 CodeGen 如何处理 TimeCardType complexType 定义中的两个元素之间的选择。默认情况下,CodeGen 将使用一个选择变量来跟踪目前处于活动状态的选择。选择中包括的值的 set 方法将允许您写入目前选择的新值,但是不能直接更改选择(如果您尝试这样做,则抛出 IllegalStateException)。要在设定后更改目前的选择,首先需要调用一个清除方法(此处为 clearReportedResourceSelect()),该方法将重置选择状态。


清单 8. HR-XML TimeCard 生成的代码样例

对于大多数应用程序来说,这类选择处理工作得非常好,可以防止用户尝试在一个选择中设置多个备选值。不过,可以使用自定义修改默认选择处理,因此如果您不喜欢这种选择处理形式,您可以轻松地更改它。choice-check 属性将控制如何在生成的代码中检查 <xsd:choice> 的选择状态。choice-check="disable" 值将禁用所有检查并且不跟踪选择状态,让用户设置一个选择状态并且每个选择只有一个值。choice-check="checkset" 与 清单 8 中所示的默认处理相符,其中只有 set 方法将检查目前的设置并抛出异常。choice-check="checkboth" 还将在调用 get 方法时检查选择状态,如果 get 方法与目前的选择状态不符,则抛出异常。最后,choice-check="override" 把默认处理修改为在设置选择的任何值时始终更改目前的状态,而不是在之前设置其他状态时抛出异常。

choice-exposed 自定义属性将与 choice-check 设置结合使用,这些设置将跟踪目前的选择状态。choice-exposed="false" 值将选择状态常量、状态变量值和状态更改方法全部设置为私有,匹配 清单 8 中所示的默认代码生成。choice-exposed="true" 将为状态变量添加 get 方法,使得所有这些内容可以公开访问。这将允许您轻松地使用 Java switch 语句以根据目前的状态执行不同的代码,而不再需要使用多条 if 语句。

这两个属性可以在任意级别的自定义中使用,允许您为最外层自定义中所有生成的代码轻松地设置行为,同时仍然保留根据具体情况执行其他操作的能力。

<xs:any> 和 mixed="true" 处理

和许多企业模式一样,HR-XML 模式将使用 <xs:any> 模式组件为数据创建扩展点,这些扩展点可以独立于原始模式,由用户定义。默认情况下,CodeGen 将使用 org.w3c.dom.Element 对象(如果 <xs:any> 中的 maxOccurs 值大于 1,则使用 Element 列表)处理 <xs:any> 模式组件。Element 对象可用于表示任意一个 XML 元素(包括所有属性、名称空间声明和内容),因此它将提供处理任何匹配模式定义的文档所需的所有灵活性。

清单 9 显示了匹配 清单 7 模式样例的 <xs:any> 组件的生成代码。由于 <xs:any> 使用 maxOccurs="unbounded",因此生成的代码将使用一个 Element 列表。


清单 9. <xs:any> 生成的代码样例

清单 9 中模式定义的某些方面是被忽略的,或者只是由 CodeGen 处理了一部分。首先,封装的 <xs:complexType> 定义指定了 mixed="true",这意味着允许将字符数据与 <xs:any> 粒子所表示的元素相混合。CodeGen 所生成的数据模型没有空间来保存这类字符-数据内容,因此在文档被解组时,这些内容将被丢弃。其次,<xs:any> 将使用 processContents="strict",意味着实例文档中存在的所有元素都需要拥有自己的模式定义。CodeGen 将忽略此属性,尽管可能使用其他形式的 <xs:any> 处理(下面将讨论)得到类似的效果。CodeGen 还将忽略 <xs:any> 名称空间限制。清单 9 使用 namespace="##any",表示匹配 <xs:any> 的元素都不受名称空间的限制,但是举例来说,如果该值是 namespace="##other",则结果应当相同。

您可以在任意级别的自定义中使用 any-handling 自定义属性,选择处理 <xs:any> 的其他方式。值 any-handling="discard" 只忽略生成的数据模型中的 <xs:any>,并在出现解组时丢弃与 <xs:any> 对应的所有元素。any-handling="dom" 将匹配默认处理,使用 org.w3c.dom.Element 表示匹配 <xs:any> 的元素。最后,any-handling="mapped" 将生成代码,要求每个匹配 <xs:any> 的元素都有一个全局模式定义(大致对应于 processContents="strict" 模式条件)。在这最后一种情况中,数据模型将使用 java.lang.Object 表示元素,并且对象的实际运行时类型匹配全局模式定义。

<xs:simpleType> 处理

和大多数通过模式生成代码的方式一样,CodeGen 将忽略或者只部分处理 <xs:simpleType> 定义的许多方面。<xs:simpleType> 限制就是这类有限支持的一个例子。在模式所定义的各种 simpleType 限制(包括长度限制、值范围,甚至正则表达式模式)中,只有 <xs:enumeration> 限制目前是在生成的数据模型中强制执行的。

CodeGen 目前也忽略 <xs:simpleType> <union>。清单 10 显示了匹配 <xs:union> 引用的生成的代码,以及匹配代码的初始模式片段(位于清单底部)。您可以在清单 10 中看到,每个指向联合(union)类型(包括清单中所示的 TimeCardDuration 类型和 AnyDateTimeType)的引用在生成的代码中是用简单的 String 值表示的。


清单 10. <xs:union> 生成的代码样例及原始模式

模式修改

如果将 清单 10 顶部的 Javadoc 中嵌入的模式片段与清单底部的实际模式片段相比较,您将看到初始模式中的 union simpleType 引用在 Javadoc 版本中已经替换为 xs:string 引用。这是故意的,并且它在 CodeGen 所执行的若干种模式结构转换中具有代表性。诸如删除 <union> simpleType 及 simpleType 限制(而非 <xs:enumeration>)之类的转换都是被硬编码到 CodeGen 操作中的。其他转换都受自定义控制。不管使用哪种方法,Javadocs 中包括的模式片段总是显示转换后的模式,因为实际上用于生成代码的就是转换后的模式。

您将在教程的后几节中看到受自定义控制的更多类型的转换。

自定义 数据模型

本教程中先前的 示例 显示了一些简单的 CodeGen 自定义。现在,您已经了解了 CodeGen 如何处理带有默认设置的 HR-XML TimeCard 模式,我们接下来将研究一些更强大的自定义。

自定义数据模型

CodeGen 使用默认设置生成的数据模型代码有一些弱点。首先,模式类型名称全都以 Type 为结尾,并且这种情况延续到对应的生成的类名上,导致名称过长。通过模式名称空间生成的包名 org.hrxml.ns 是合理的,但是如果包名可以表明该数据模型专门用于 TimeCard 文档,那么效果会更好。

清单 11 显示了生成的数据模型类的另外一个缺点,其中 java.math.BigInteger 用于表示 xs:integer 类型。这是使用标准 Java 类时 xs:integer 的最精确表示,但是与简单的 int 原语或 java.lang.Integer 对象类型相比,BigInteger 并不好用。糟糕的是,即使使用 xs:int 会更恰当,人们也通常使用 xs:integer 类型编写模式,因此开发人员可能会在生成的代码中遇到 BigInteger 值。本例就是这种情况:GenderCode 允许的实际值全都是个位数(如清单底部的原始模式片段所示)。


清单 11. xs:integer 生成示例

清单 12 显示了可以改进生成数据模型的这些缺点的自定义。package="org.hrxml.timecard" 属性将提供用于生成的类的 Java 包。type-substitutions="xs:integer xs:int" 属性将定义 CodeGen 所应用的模式类型置换,在本例中使用 xs:int 类型替换模式中引用的 xs:integer。通过向列表中添加更多类型名称,使用空格分隔每对置换以及其中的类名,您可以定义多对置换。

嵌套的 name-converter 元素将确定如何处理被转换为 Java 名称的 XML 名称。在本例中,strip-suffixes="Type" 属性将告诉 CodeGen 只要 Type 出现在名称末尾就删除它。您可以用一张用空格分隔的列表来提供要通过此属性删除的多个备选内容。您也可以使用 strip-prefixes 属性删除名称中不必要的前导文本,以及其他几种形式的自定义。如果您需要在名称转换中执行一些特殊操作,甚至可以用您自己的实现来替换默认的名称转换类。有关这些 name-converter 选项的完整信息,请参阅 JiBX CodeGen 文档。

最后,嵌套的 class-decorator 元素将向代码生成序列中添加一个修饰符(decorator)。在本例中,修饰符是 CodeGen 发行版中提供的预定义内容,它将添加用于集合值的有用的支持方法。在 CodeGen 构造数据模型类的源代码时,它将按顺序调用所有已配置的代码生成修饰符,并且这些修饰符可以进行修改或者添加到 CodeGen 生成的字段、方法和类构造中。使用 Eclipse AST 实现,把所有这些构造作为抽象语法树(Abstract Syntax Tree,AST)组件传递给修饰符。提供的修饰符(包括在这里用于添加方法的 org.jibx.schema.codegen.extend.CollectionMethodsDecorator 修饰符,以及用于向数据模型类中添加 java.io.Serializable 接口和可选的版本 id 的 org.jibx.schema.codegen.extend.SerializableDecorator)演示了如何结合使用 Eclipse AST 以扩展 CodeGen,因此这些类的源代码是编写您自己的修饰符的最佳起点。


清单 12. TimeCard 自定义示例

					
<schema-set xmlns:xs="http://www.w3.org/2001/XMLSchema" package="org.hrxml.timecard"
    type-substitutions="xs:integer xs:int">
  <name-converter strip-suffixes="Type"/>
  <class-decorator class="org.jibx.schema.codegen.extend.CollectionMethodsDecorator"/>
</schema-set>

您可以使用 custgen1 Ant 目标尝试执行清单 12 中的自定义,也可以使用 custom1 目标运行完整的生成、编译、绑定及测试操作。清单 13 显示了应用自定义的结果。TimeCardType 类名已经改为 TimeCard,并且除了 List get 和 set 方法之外,现在还添加了 size、add、indexed get 和 clear 方法。在 GenderCode 类中,BigInteger 引用已经被替换为一个简单的 int 原语类型。


清单 13. 自定义的数据模型

清除不使用的定义

在使用初始简单模式的第一个自定义示例中,您看到了通过使用 generate-all="false" 禁止生成每个全局定义,并使用 includes 列表强制生成特定定义,从而控制生成的数据模型中包括的类型定义。清单 14 显示了添加了这些属性的 TimeCard 模式的修改后的自定义,只包含要包括到生成的数据模型中的 TimeCard 元素(当然,还包含 TimeCard 表示所使用的一切内容)。


清单 14. 只包含 TimeCard 组件的自定义

					
<schema-set xmlns:xs="http://www.w3.org/2001/XMLSchema" package="org.hrxml.timecard"
    type-substitutions="xs:integer xs:int" generate-all="false">
  <name-converter strip-suffixes="Type"/>
  <class-decorator class="org.jibx.schema.codegen.extend.CollectionMethodsDecorator"/>
  <schema name="TimeCard.xsd" includes="TimeCard"/>
</schema-set>

您可以使用 custgen2 Ant 目标尝试用 CodeGen 使用此自定义,或者使用 custom2 目标运行完整的生成、编译、绑定及测试。此更改将把数据模型中顶级类的数目从 15 个减少到 10 个 — 这是简化数据模型的好开端。

自定义独立组件

到目前为止,您只看到了在整套模式中或者独立模式中应用的自定义示例。您还可以自定义 CodeGen,使其处理模式定义内 的特定组件,包括全局定义及嵌入到全局定义中的内容项。可用的自定义包括从数据模型中清除组件、更改组件使用的类或值的名称,以及更改组件的模式类型。

如果要控制模式,则从数据模型中清除组件的自定义不是特别有用 — 在那种情况下,直接更改模式始终更简单些。但是企业数据交换模式通常包括专用组件,这些专用组件可能不适合用于使用这些模式的特定应用程序,并且这些模式通常不在您的控制范围内。在这种情况下,使用自定义将允许您简化数据模型,而无需触及提供的模式。

组件自定义

模式组件的自定义方式是,把自定义元素与表示组件的模式定义元素关联在一起。您可以使用多种不同的方法建立自定义与模式元素之间的关联,因为在特定情况下,一种方法可能比另一种方法更方便。不过,关联有一部分是固定的:自定义元素的名称必须始终与模式组件元素名称相符。因此要自定义模式中的 <xs:element> 定义,您需要使用 <element 自定义元素(没有名称空间)。

清单 15 将显示来自 TimeCard 所引用的其他模式之一的定义,它很好地演示了单个组件的自定义。PersonNameType 包含几个简单的 xs:string 元素,以及一些带有复杂结构的其他元素。教程代码中使用的测试文档恰巧不包括这种类型的 Affix 或 AlternateScript 元素的任何实例,因此清除它们以简化生成的数据模型再合适不过。


清单 15. PersonName 模式

清单 16 显示了一种定义自定义以从数据模型中清除 Affix 和 AlternateScript 元素的方法。这种方法将使用路径指定,这是一种浏览模式定义结构的类似 XPath 的方向集合。路径步骤是通过斜杠(/)字符来分隔的,并且,匹配模式定义的命名组件(全局类型、组或 attributeGroup 定义,或者不管是否是全局性质的元素或属性定义)的步骤可以使用 [@name=...] 断言(predicate)来挑选组件类型的特殊实例。


清单 16. 直接自定义不需要的组件

在 清单 16 中,每条路径都是从模式级别完整拼写的。您还可以在路径中使用通配符。* 通配符作为路径的一部分将匹配模式定义中的所有单个元素,而 ** 通配符将匹配模式定义中的任意数目的嵌套元素。因此不要使用 complexType[@name=PersonNameType]/sequence/element[@name=Affix] 路径,您可以转而使用 complexType[@name=PersonNameType]/*/element[@name=Affix] 或 complexType[@name=PersonNameType]/**/element[@name=Affix]。可是,您不能使用 **/element[@name=Affix] — CodeGen 要求您明确识别任何自定义中涉及的全局定义组件,作为防止错误地应用自定义的安全措施。

只要嵌套匹配模式定义结构,那么就可以嵌套组件自定义。在这种情况下,每个自定义只需指定与包含的自定义相关的目标。您还可以在自定义中使用 name="..." 属性替代路径的最后一步中的 [@name=...] 断言,并且可以跳过最后一步的元素名称(因为它必须始终与自定义元素的名称相同)。您甚至可以完全避免使用路径,而使用结合了名称属性的嵌套。清单 17 显示的自定义与 清单 16 相同,只是进行了重构,使用了这种备选方法:


清单 17. 嵌套自定义不需要的组件

					
<schema-set ...>
  <schema name="PersonName.xsd">
    <complexType name="PersonNameType">
      <sequence>
        <element name="Affix" ignore="true"/>
        <element name="AlternateScript" ignore="true"/>
      </sequence>
    </complexType>
  </schema>
</schema-set>

简化数据模型

除了在前一小节中用作示例的 PersonName 组件之外,TimeCard 模式还具有大量未在本教程的样例文档中使用的其他复杂组件。通过使用自定义清除这些未使用的组件,可以大大简化生成的数据模型。在某些情况下,CodeGen 所使用的 Java 值名称无法正常工作。尤其是重复使用同一个元素名称会导致只能通过数字后缀区分值名称,因此很难了解如何正确使用值。参见 清单 10 中的示例,其中生成的代码中包括一对名为 duration 和 duration1 的字段。您可以使用自定义将这些名称改为更有意义的名称。

清单 18 将显示来自代码的 hrxml 目录中的 custom3.xml 文件,该文件包括所有这些自定义。该清单有意使用前一小节讨论的各种识别组件的方法,结合了嵌套、路径,以及包含有名称的路径。值名称自定义位于底部,使用 value-name="simpleDuration" 属性把第二个 duration 使用的名称改为更具描述性的形式。


清单 18. 简化 TimeCard 数据模型并使其含义更清晰

您可以使用 custgen3 Ant 目标尝试用 CodeGen 使用此自定义,或者使用 custom3 目标运行完整的生成、编译、绑定及测试。自定义将把生成的类的数量减少到 9 个顶级类和 10 个内部类,总计 19 个类。这刚好是未使用自定义的初始数据模型中的类数目的一半。

CodeGen 命令行参数

除了在教程代码中使用的那些命令行参数之外,CodeGen 还支持若干个附加命令行参数。表 1 列出了最重要的选项:


表 1. CodeGen 命令行选项

命令用途
-c path 输入自定义文件的路径
-n package 无名称空间的模式定义的默认包(默认为默认包)
-p package 所有模式定义的默认包(默认为使用从各个模式名称空间生成的包)
-s path 模式根目录路径(默认为当前目录)
-t path 生成的输出的目标目录路径(默认为当前目录)
-v 冗余输出标志
-w 在生成输出前从目标目录中删除所有文件(如果目标目录就是当前目录,则忽略)

通过在自定义属性值之前使用特殊的 -- 前缀,您还可以将全局自定义作为命令行参数传递给 CodeGen,而无需创建自定义文件。因此,要设置 清单 5 的自定义中使用的全局选项,您需要向 CodeGen 命令行中添加 --prefer-inline=true --show-schema=false --enumeration-type=simple --generate-all=false(可是,使用这种方法您无法指定要在生成中包括的模式组件列表,因为这些模式组件是专门用于特定模式的)。在使用这项技术时,不需要对属性值使用引号。如果需要设置获取多个值的列表的自定义,则使用逗号而不要使用空格作为各个值之间的分隔符(这样将忽略 Type 和 Group 模式名称后缀,例如,使用命令行 --strip-suffixes=Type,Group 参数)。

 

结束语

在本教程中,您首先了解了使用 JiBX 通过 XML 模式定义生成 Java 数据模型,然后在匹配该模式的文档与数据模型之间来回转换。还了解了如何使用自定义控制数据模型的生成方式。除了本教程中介绍的自定义之外,还有许多其他自定义可用于控制数据模型的各个方面。JiBX 文档将提供所有这些自定义选项的完整信息,以及通过模式生成代码的更多示例。

Web 服务定义是 XML 模式的主要应用之一。JiBX 目前可以在 Apache Axis2、Apache CXF、XFire 和 Spring-WS Web 服务堆栈中使用,并且它还支持它自己的 JiBX/WS 形式的轻量级 Web 服务引擎。您可以对这些 Web 服务堆栈中的任意一个使用本教程讨论的通过模式生成代码的功能,不过目前还需要先通过 Web 服务描述语言(Web Services Description Language,WSDL)服务定义提取模式定义,然后才能生成。您还需要执行针对每个堆栈的附加步骤才能得到有效的 Web 服务。JiBX 的未来版本将简化创建 Web 服务实现的过程,因此请查阅 JiBX 发行版中的文档以了解该领域中的所有新功能。

jibx 开发指南 Jibx完成Java到XML的相互转换 Jibx完成Java到XML的相互转换 Jibx 开发指南 xml 转换 序列化 立即下载

相关推荐

JiBx 1.3.1

JiBx是一个优秀的绑定Java对象与XML文件的工具,1.3.1版本可以与jdk1.8完美兼容

java xml 代码_XML模式到Java代码

在你开始前 关于本教程 JiBX是用于将XML数据绑定到Java™对象的工具。 长期以来,JiBX数据绑定是将Java代码绑定到XML的最快,最灵活的方法。 但是,其绑定定义的复杂性以及对日益广泛使用的XML模式定义的有限支持有时使用户感到沮丧。 幸运的是,JiBX的1.2版本对于消除这些问题大有帮助。 在本教程中,您将学习如何使用JiBX 1.2的新功能轻松地从XML模式定义生成Ja...

cusi77914的博客 912

昇腾Atlas Duo 300I推理卡实战:从零部署Qwen大模型推理服务

本文详细记录了在华为昇腾Atlas Duo 300I推理卡上,从零部署Qwen1.5-14B-Chat大模型推理服务的完整实战过程。涵盖环境准备、MindIE容器配置、CANN工具链安装、服务启动与API测试等关键步骤,并分享了性能观察与排错经验,为国产AI算力平台部署LLM推理服务提供了实用指南。

weixin_29084231的博客 1239

JIBX的工具使用

JiBX是一款优秀的XML数据绑定框架。它提供灵活的绑定映射文件,实现数据对象与XML文件之间的转换,并不需要修改既有的java类。 它的主要优点:转换效率高、配置绑定文件简单、不需要操作xpath文件,不需要写get/set方法,对象属性名与xml文件element名可以不同等等。 它与JAXB的比较:不同于jaxb,jibx使用java字节码enhance技术,而jaxb更多在于源代码生成

a329661511的博客 2103

告别盲目调参:手把手教你用RKISP2.x Tuner理解AWB、AE、NR等核心模块

本文详细介绍了如何使用RKISP2.x Tuner工具进行ISP调试,重点解析AWB、AE、NR等核心模块的调参技巧。通过RV1126平台的实际操作演示,帮助工程师快速掌握可视化对比实验方法,告别盲目调参,提升图像信号处理效率。

weixin_30300225的博客 393

深入解析Android Qcom Camera HAL3架构与Camx线程模块

本文深入解析了Android Qcom Camera HAL3架构与Camx线程模块的核心原理。文章以高通芯片平台为例,剖析了从按下快门到生成照片的完整Camera流程分析,重点阐述了Camx框架中线程池、消息队列及Fence同步机制如何协同工作,以实现高效、稳定的多线程并发图像处理,为相机性能优化提供理论基础。

weixin_29184075的博客 221

java enum 多个字段_java – 如何使用允许jibx中的多个枚举值的...

我想使用Jibx来解组以下XML(存储在名为test.xml的文件中):我定义了模式(在一个名为simple.xsd的文件中),如下所示:使用org.jibx.schema.codegen.CodeGen工具从中生成Java文件并编写此测试程序:package test;import java.io.File;import java.io.FileInputStream;import java.i...

weixin_39643336的博客 450

scRNA-seq | 吐血整理的单细胞入门教程(从原理到代码实操)(二)

scRNA-seq | 吐血整理的单细胞入门教程(从原理到代码实操)(二)

m0_72224305的博客 4306

JiBX 的实操

你了解JiBX 吗? 知道如何实现XML和POJO对象的快速转换吗? 本文非常详细的教大家如何一步步实现功能,包括代码和截图。再难的技术,只要我们一步步动手去实现它,我们就能完成量变到质变的转变。

echohuangshihuxue的博客 1127

R语言基础之R语言入门

R语言最初是由新西兰奥克兰大学统计系的教授Ross Ihaka和Robert Gentleman在S语言基础上开发完成的。是一门解释性语言。在我看来R语言是一门数学性极强的语言,或者说这是一门为数学而生的语言,因为其具有极其出色的计算与统计分析能力...

weixin_46912400的博客 5万+

23、工业物流中的多智能体路径规划与碰撞处理策略

本文探讨了工业4.0背景下工业物流中的多智能体路径规划(MAPF)与碰撞处理策略。分析了自动导引车(AGV)等移动资源的应用现状,综述了主流路径规划算法如A*、D*Lite、M*等,以及集中式与分布式碰撞检测方法。重点比较了五种碰撞避免策略:路径交叉、优先级、起始时间调整、无交叉路径和速度调整,提出了基于环境条件的策略选择流程,并通过流程图展示了评估、组合、测试与优化的全过程。文章强调应根据订单不确定性、时间约束、优先级和生产组织等因素综合选择或组合策略,以提升物流效率与系统可靠性。

mac99的博客 125

jibx结合maven,ant初次使用详细步骤

最近在看<<netty指南第二版>>,看到了netty结合http+xml协议栈开发,需要用到jibx,本人首次使用jibx,一时间犯了难.网上看了很多帖子,大都是下载好jar包,然后在cmd窗口中运行Java -jar命令 .由于公司内部屏蔽了许多外网导致,jibx的jar包下载不了.后来多次尝试.利用maven和ant成功实现了jibx的初次使用,特此记录. 1,本地创建maven工程,在pom中添加如下依赖 <!-- https://mvnrepository.co

xilin6664的博客 734

linux v3h平台开发系列详解(GMSL摄像头篇):1.12 解串器MAX96712输出4 lane 变 2 lane的配置

本文详细介绍了在Linux v3h平台上,针对Max96712解串器进行MIPI 4lane到2lane配置。内容包括串行器解串器介绍、链路框架、硬件连接、以及软件寄存器如何配值和一些问题的解决方法。

xian18809311584的博客 1094

JiBX 1.2,第 2 部分: 从 XML 模式到 Java 代码,通过 XML 模式生成更干净的自定义 Java 代码...

安装 JiBX 在继续学习本教程之前,您需要先安装 JiBX。下载 最新的 1.2.x 发行版 ZIP 并将其解压缩到系统中便于访问的位置。您将得到名为 jibx 的目录,其中包含所有的 JiBX JAR、文档、示例,甚至源代码。 安装教程代码 现在下载教程 样例代码,也是以 ZIP 文件的形式提供的。在系统中安装样例代码的最简单方法是在 JiBX 安装的根目录中解压缩 ZIP(或者对于 W...

zhangziyangup 281

ArcGIS实验教程——实验二:ArcGIS地理配准完整操作步骤

本文介绍ArcGIS 10.2中地理配准的完整操作流程,涵盖加载扫描地图、启用地理配准工具条、添加控制点(含经纬度输入与坐标系统选择)、均匀分布控制点以提升精度,并最终通过“更新地理配准”完成栅格数据的空间定位。强调控制点数量、分布及坐标系匹配的重要性,附带实验数据下载链接与获取方式,适用于初学者掌握扫描矢量化前的关键几何校正技能。

智慧空间实验室 9万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

java xml 代码_Java代码到XML模式

在你开始前 关于本教程 JiBX是用于将XML数据绑定到Java对象的工具。 长期以来,JiBX数据绑定是将Java代码绑定到XML的最快,最灵活的方法。 但是,其绑定定义的复杂性以及对日益广泛使用的XML模式定义的有限支持有时使用户感到沮丧。 幸运的是,JiBX的1.2版本对于消除这些问题大有帮助。 在本教程中,您将学习如何使用JiBX 1.2的新功能从现有Java代码轻松生成XML...

cuxiong8996的博客 607

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【HTTP+XML】JiBX生成Order相关

netty权威指南第二版、http+xml、Order、build.xml、JiBX

不放糖的咖啡 1702

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

jibx java_XML 和 Java 技术:数据绑定第 4 部分: 使用 JiBX

JiBX 首席开发人员 Dennis Sosnoski 为您展示了如何在 Java 应用程序中使用他新创建的用于 XML 数据绑定的框架。利用 JiBX 使用的绑定定义,您可以真正控制数据编组(marshalling)和数据编出(unmarshalling)的所有方面,包括处理 XML 文档与相应的 Java 语言对象之间的结构区别。想要重构您的代码而又不更改 XML 表示吗?利用 JiBX,您可...

weixin_29290259的博客 334

java jibx_Jibx 处理XML

它们都可以完成Java对象到XML的转换,但是还不是那么的完善。还有XStream对JSON及XML的支持,它可以对JSON或XML的完美转换。在线博文:Jibx对Java对象的转换相对要负责些,它不仅需要配置xml还且还要生成相应的jar文件,已经xsd文件。下面我们就来慢慢看看Jibx转换Java到XML是如何完成的。一、准备工作1、 准备资源c) 依赖jar包如下: 2、 程序准备代码pa...

weixin_36230923的博客 439

JiBx:BindGen命令行--通过Java POJO对象产生bind.xml和xsd文件

JiBx:BindGen命令行--通过Java POJO对象产生bind.xml和xsd文件1. 官网下载JiBx包 最新版本的zip包是: jibx_1_2_6.zip2. 解压 我这里解压后的路径是: I:\Tech\2016\JiBx\jibx_1_2_6 3. 了解BindGen类使用方法 在lib目录下找到核心jar:jibx-tools.jar 在Windows的comma

hills的专栏 3421

基于JiBX框架的XML数据与POJO对象的转换

使用JiBX绑定XML文档与Java对象需分两步走:① 绑定XML文件,也就是映射XML文件与Java对象之间的对应关系;在运行程序前,需要先配置绑定文件并进行绑定操作,在绑定过程中它将动态修改程序中对应的class文件,主要是生成对应对象实例的方法和添加被绑定标记的属性JiBX_bindingList等。④ 进入POJO class文件路径,使用JiBX工具生成bing.xml绑定文件已经XML数据格式定义文件,并将文件拷贝到Maven工程src\main\resources目录下。

譚潇逺的博客 768

Jibx插件的使用

  Jibx是一款非常优秀的XML文件数据绑定的框架,提供灵活的绑定映射文件,实现数据对象和XML文件之间的转换,并不需要修改既有的Java,另外,它的转换效率是目前很多其他开源项目都无法比拟的。本文来演示下如何使用 Jibx插件的使用 下载Jibx插件: 链接:https://pan.baidu.com/s/1Va9D8LZlxoVU5VndC7T1ag 提取码:oyjt Pojo创建 Ord...

波波烤鸭的博客 2727
上一篇: 利用 WAS CE v2.1 创建基于 JMS 的应用
下一篇: JiBX 1.2,第 1 部分: 从 Java 代码到 XML 模式,通过 Java 数据模型与 XML 文档之间的自定义转换提高模式质量
phantomhu
博客等级 码龄23年 70粉丝 24原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值