`

Java 中的XML: 数据绑定 代码生成方法 — JAXB 及其它

    博客分类:
  • xml
阅读更多

企业 Java 专家 Dennis Sosnoski 研究了几种 XML 数据绑定方法,这些方法根据用于 XML 文档的 W3C XML Schema 或 DTD 文法来生成代码。他从人们期待已久的 JAXB 标准(马上就要由 Java Community Process,JCP 发布了)入手,然后总结了其它一些目前可用的框架。最后,他讨论了如何以及何时以最佳方式将依据文法的代码生成应用到应用程序中。

 

数据绑定 提供了一种简单而直接的方法,以在 Java 平台应用程序中使用 XML。有了数据绑定,应用程序可以在很大程度上忽略 XML 文档的实际结构,而直接使用那些文档的数据内容。虽然这种方法不能适合于所有应用程序,但在一般情况下,对于那些将 XML 用于数据交换的应用程序是比较理想的。

除了简化编程之外,数据绑定还提供了其它一些好处。由于数据绑定对许多文档细节进行了抽象,因此对于在内存中处理文档,它通常所需要的内存比文档模型方法(譬如 DOM 或 JDOM)要少。您还会发现,由于不需要遍历文档结构以获取数据,因此用数据绑定方法访问程序内的数据要比用文档模型方法快。最后,在输入时,一些特殊类型的数据(譬如数字和日期)可以被转换成内部表示,而不是保留为文本形式;这使应用程序可以更有效地使用数据值。

您可能想知道,如果数据绑定有这么多的好处,那么何时使用文档模型方法呢?基本上在以下两种主要情形下需要用文档模型方法:

  • 当应用程序确实要关注文档结构的细节时。例如,如果您正在编写一个 XML 文档编辑器,则您会希望采用文档模型,而不是使用数据绑定。
  • 当正在处理的文档不需要遵循固定的结构时。例如,对于实现常规的 XML 文档数据库,数据绑定不是一种很好的方法。

回到绑定

去年,我写了一篇文章,讲述了如何使用 Castor 框架以进行 Java 对象到 XML 文档的映射数据绑定。我曾经答应要写一篇后续文章,其中将探讨代码生成方法,包括介绍 JAXB,Java Community Process(JCP)正在开发 JAXB,它是用 Java 语言编写的、用于数据绑定的标准 API。就在较早的那篇文章发布不久,Sun 宣布对 JAXB 的方向做出了重大调整(请参阅 重新架构 JAXB)。由于这方面的变化,所以我想,为了更贴近最终的 JAXB 代码,最好先不写这篇后续文章,现在,我很高兴,终于可以写这篇文章了!

数据绑定字典

下面是一个微型字典,里面包含了我在本文中所使用的一些术语:

文法(Grammar) 是用于定义一系列 XML 文档结构的一套规则。其中一类文法是 XML 规范所定义的文档类型定义(Document Type Definition,DTD)格式。另一类日渐普及的文法是 XML Schema 规范所定义的 W3C XML Schema(Schema)格式。文法定义了哪些元素和属性可以出现在文档中,以及在文档中元素是如何嵌套的(通常包括嵌套元素的次序和数目)。一些类型的文法(譬如 Schema)还可以更进一步,使字符数据内容与特定数据类型甚至正则表达式相匹配。在本文中,我会常使用术语 描述, 将它作为引用一系列文档的文法的非正式方法。

编组(Marshalling)是在内存中为对象生成 XML 表示的过程。与 Java 对象序列化一样,这种表示需要包含所有依赖的对象:我们的主对象引用的对象、这些对象引用的对象等等。

数据分解(Unmarshalling) 是与编组相反的过程,在内存中根据 XML 表示构建一个对象(而且可能是链接对象的图)。

在本文中,我将讨论根据 XML 文档文法生成 Java 语言代码的五种 XML 数据绑定框架:JAXB、Castor、JBind、Quick 和 Zeus。它们都可以免费获取,除了 JAXB 之外,其它四种框架都可以在开放源码和专利项目中使用。当前 JAXB 参考实现 beta 测试版的许可证只允许用于评估,但当它作为产品发行时,这种情形很可能会改变。JAXB、Castor 和 JBind 都提供了根据 XML 文档的 Schema 描述生成代码,而 Quick 和 Zeus 根据 DTD 描述生成代码。Castor 和 Quick 还支持将现有类映射到 XML,以此作为另一种生成代码的方法。

 

这些框架各有优缺点,所以我会试图逐步指出每种框架所具有的最佳(和最差)特性。在第 2 部分,我将进一步向您显示这些框架如何对一些样本文档进行处理,另外,还将探讨,对于许多类型的应用程序,现有的数据绑定框架怎么会缺乏一些重要的特性。

 

相对于我在以前文章中所描述的映射绑定方法,根据 Schema 或 DTD 文法生成 Java 语言代码具有一些突出的优点。使用生成的代码,您可以确定数据对象被正确地链接到 XML 文档,不象映射绑定方法,需要直接指定链接,并确保正确地涵盖了所有的结构变体。在使用 Schema 时,甚至可以利用文法所提供的类型信息,用合适的数据类型来生成代码。

代码生成方法也有一些不足之处。这种方法造成应用程序数据结构与 XML 文档结构之间紧密耦合。另外,它还可能限定您使用简单的数据类(没有关联行为的被动数据容器),而不是真正的对象类,在编组和数据分解过程中,还可能限制应用数据的定制转换的灵活性。在本文后面,我会权衡代码生成和映射绑定这两种方法(请参阅 映射绑定 vs. 代码生成)。

 




回页首


数据和代码

对于将在第 2 部分中讨论的性能测试,我用每一种数据绑定框架来生成代码。用于性能测试的文档包含模拟航班时刻表的信息。下面是一个样本文档,您可以感受一下其中的结构:


清单 1. 样本文档

<?xml version="1.0"?>
<timetable>
    <carrier ident="AR">
        <rating>9</rating>
        <URL>http://www.arcticairlines.com</URL>
        <name>Arctic Airlines</name>
    </carrier>
    <carrier ident="CA">
         <rating>7</rating>
       <URL>http://www.combinedlines.com</URL>
        <name>Combined Airlines</name>
    </carrier>
    <airport ident="SEA">
        <location>Seattle, WA</location>
        <name>Seattle-Tacoma International Airport</name>
    </airport>
    <airport ident="LAX">
        <location>Los Angeles, CA</location>
        <name>Los Angeles International Airport</name>
    </airport>
    <route from="SEA" to="LAX">
        <flight carrier="AR">
          <number>426</number>
          <depart>6:23a</depart>
          <arrive>8:42a</arrive>
        </flight>
        <flight carrier="CA">
          <number>833</number>
          <depart>8:10a</depart>
          <arrive>10:52a</arrive>
        </flight>
        <flight carrier="AR">
          <number>433</number>
          <depart>9:00a</depart>
          <arrive>11:36a</arrive>
        </flight>
    </route>
    <route from="LAX" to="SEA">
        <flight carrier="CA">
          <number>311</number>
          <depart>7:45a</depart>
          <arrive>10:20a</arrive>
        </flight>
        <flight carrier="AR">
          <number>593</number>
          <depart>9:27a</depart>
          <arrive>12:04p</arrive>
        </flight>
        <flight carrier="AR">
          <number>102</number>
          <depart>12:30p</depart>
          <arrive>3:07p</arrive>
        </flight>
    </route>
</timetable>

 

图 1 显示了用于映射数据绑定到这些文档的类结构。为了进行比较,我将在有关各个数据绑定框架章节中显示生成的类结构。这里包含的这些图仅仅是所有情况的缩略图;如果要看全图,请单击这个小图像。

图 1. 映射绑定类图(单击进行放大) 




回页首


JAXB 面前的漫漫长路

用于 XML 绑定的 Java API(Java API for XML Binding,JAXB)是一个处于不断发展中的 Java 平台数据绑定标准。Java Community Process 正在开发作为“JSR-31 ― XML 数据绑定规范(XML Data Binding Specification)”的 JAXB。该项目始于 1999 年 8 月,其目的是定义一种方法,生成与 XML 结构相链接的 Java 语言代码。最初打算在 2000 年第 2 季度发布,但最后在 JavaOne 2001 上宣布了初步的 Early Access(EA)版本,该版本在 2001 年 6 月向公众发布。

 

JAXB 的 EA 版本基于具有创新意义的拉解析器(pull parser)设计,这种设计使验证可以方便地构建到生成的数据分解代码中。它根据 DTD 生成代码,构建在解析 XML 文档时自动验证 XML 文档结构(而不是数据)的类。我们期望这种方法能快速和有效地处理 XML 和 Java 语言对象之间的转换,但 EA 代码仅仅是部分实现,显然在成为完整的实现之前,仍需要做大量工作。

 

专家组不久之后开始收到关于 EA 发行版的反馈。作为对反馈意见的部分响应中,他们研究决定重新架构 JAXB,之后更新了网站,声明 JAXB 在几个方面正在得到增强。该站点还声明,下一版本在 API 级上不与早期版本兼容 ― 但您仍然可以下载 EA 版本。

 

 

重新架构 JAXB

直到 2002 年 3 月,新体系结构的细节才公布于众,在 JavaOne 上,Sun 宣布,作为在 JAXB 方面进一步工作的基础,实际上正在放弃 EA 代码。它将被新设计所替代,在新设计中,共享了一些常见的功能,但新设计使用不兼容的 API 和内部体系结构。发展方向变化如此之大,让我和那些对 EA 代码有兴趣的人们感到惊讶。

 

JAXB 项目的 SUN JSR 负责人 Joseph Fialli 把这么大的变化归结为以下一些因素。主要问题是扩展原有代码库以支持 W3C XML Schema 的复杂性。这是一个相当复杂的规范,以至于在批准之后的两年多时间里,在所有平台上,仍然只有少数几个解析器能接近完全符合规范。最初的 JAXB 代码需要实际对象来控制验证,而且将这种方法扩展到 Schema 将耗费太多精力,以至于在合理的期限内无法实现这项工作。

 

为适应 Schema 而做出变更的同时,专家组还决定重新考虑处理验证的方法。原来的 JAXB 代码无条件地验证文档的结构,如果发现错误,则抛出异常并中止处理。Fialli 说,在公众的意见中,抱怨这种方法局限性太大、限制太严 ― 在一些情况下,用户希望能够一次检查多个验证错误,而在另一些情况下,则希望完全禁用验证(或者由于性能原因,或者在编组没有精确匹配文法的文档时)。新的 JAXB 体系结构能够满足这两种需求。

 

最后,专家组决定放弃单个绑定框架运行时(就象在原来 EA 发行版中所看的)的想法。而采用接口方法,其实质是可以使用不同的数据绑定框架。这使用户代码可以在各框架之间进行移植,而不需移植生成的类 ― 这些类特定于专门的数据绑定框架,它们只能由该框架运行。强制性的 SAX 2.0 解析器支持替代了 EA 运行时中所使用的拉解析器方法,对于其它解析器(可能包括新的拉解析器,该解析器基于用于 XML 的流式 API,JSR 173 正在定义此 API),提供可选的特定于框架的支持,数据结构本身被更改为类 JavaBean 的数据对象,外部框架可以方便地操作此数据对象。

 

JAXB beta 测试版

自 3 月以来,JAXB 项目一直在朝着这个新方向前进。这一工作的第一个公开成果是,去年夏天发布了该规范的新草案(但草案仍处于准备阶段)。接着在 10 月,Sun 提供了 JAXB 参考实现新的 beta 测试版,最终它会替代过时已久的 EA 版本。在这些文章中,我用这个最近的 beta 测试版进行评估和性能测试。它直接根据 Schema 文档描述进行工作,生成与为文档所定义的元素类型和用法相匹配的类的层次结构。该层次结构包括四种常规类型的类:用于已定义类型的接口、用于实际元素的接口和这两组接口的实现。

图 2. JAXB 接口类图(单击进行放大) 

图 3. JAXB 实现类图(单击进行放大) 


 

从应用程序的角度来看,类型接口是这些类最有趣的部分。对于类型内的数据,存在着 JavaBean 样式的 get 方法和 set 方法集合。包含在类型接口中的这些方法遵循 JAXB 规范所规定的规则,所以应用程序代码可以安全地使用这些接口来访问所有数据,同时还保持了 JAXB 实现间的可移植性。这些接口使 JAXB 生成的代码可以相当容易地与现有文档一起使用。然而,构造和修改数据结构有点困难。因为使用接口,所以不能直接构造实例;而是必须使用工厂方法创建实例,然后使用类 JavaBean 的取值方法来填充数据值。

 

用 JAXB 根据 Schema 描述生成代码非常简单。所提供的绑定编译器 xjc 是一个命令行工具。它将 Schema 文档作为输入,将文件生成到指定的输出包和目标目录。其中所具有的选项还使用户可以控制生成的代码文件是否是只读的,以及是否严格验证 Schema 描述。

 

通过使用绑定声明,JAXB 规范定义了一些方法来定制生成数据绑定的一些方面。包括:

  • 用于控制所生成类的名称和属性的选项
  • 指定由绑定所使用的现有实现类的方法
  • 允许(有限地)控制验证处理和用于编组和数据分解的序列化器/反序列化器(serializer/deserializer)的选项

要么在实际的 Schema 文档中以注释形式嵌入这些定制,要么通过使用单独的外部绑定声明文档来单独提供这些定制。参考实现的当前 beta 测试版只支持第一种方法,但在以后的发行版中将支持使用外部绑定声明文档。

 

总体说来,JAXB 正成为一种功能强大而灵活的工具,它用于将 Java 语言代码绑定到 W3C XML Schema 文法所定义的文档。由于有可能批准将 JAXB 作为一个 Java 平台标准,因此它将会受到广泛支持,而且在各实现之间移动绑定应用程序会象在 servlet 引擎之间移动 Web 应用程序一样容易(一般来讲,很简单,但偶尔也会有一些波折)。

 

然而,JAXB 确实也有一些缺点。目前最大的局限是只有用于评估用途的许可证。在该产品发行版(目前计划在这个季度发布)之前,JAXB 还无法用于实际项目中。另外,定制的程度也局限于只能应用到生成的代码。在许多情形中,您可以为 JAXB 所定义的接口定义自己的实现类,但这些接口本身总是与 Schema 描述联系在一起,不太可能进行修改。

 

 

Castor

用于 XML 数据绑定的 Castor 框架支持映射绑定和生成绑定。在我的上一篇文章中,我讨论了 Castor 映射绑定方法的一些特性。对于本文,我只讨论根据 Schema 生成代码,但在第 2 部分,我将研究这两种方法的性能。请回顾以前的文章(请参阅 参考资料),了解有关 Castor 中映射数据绑定工作方式的更多信息。

图 4. Castor 生成的类图(单击进行放大) 


 

在一些细节上,Castor 的代码生成支持不同于 JAXB 方法,但在目的上,两者非常相似。与使用 JAXB 一样,Castor 向应用程序提供类 JavaBean 结构的数据模型。主要差别在于 Castor 避免使用接口,而是喜欢直接使用生成的实现类。除了每个实现类,Castor 还生成描述符(descriptor)类,该类包含绑定和验证代码。由于 Castor 使用具体的类,而不是接口,因此对于构造或修改文档数据结构,它要比 JAXB 略微简单。可以仅仅直接使用相应类的构造函数,而不用通过工厂类。

 

Castor 的当前 beta 测试版(我写这篇文章时,该版本为 0.9.4.1)不支持在代码生成中进行任何实质的定制,但这种情况有望得到改变。下一 beta 测试发行版预计将支持使用映射文件来控制代码生成的各个方面。起初,在这些方面中,只支持类名和包名,但从更长远来看,计划将添加对用户所提供的实现类的支持。Castor 开发人员还计划在 Castor 中支持 JAXB,可能是通过使用某类兼容性层来实现这一点。

 

用 Castor 根据 Schema 描述生成代码与用 JAXB 一样方便,使用的基本选项也一样。Castor 确实使用一些附加的命令行参数选项,而且通过属性文件设置,甚至提供了更多选项。这些选项主要用在一些特殊的情形中,但不包括象 JAXB 那样通过 Schema 文档注释提供对类名和验证的控制。

 

现在,用 Castor 来生成源代码这种方法的主要缺点是对定制的支持有限。这种情形正在开始发生转变,可以用 Castor 的映射数据绑定方法来实现实质的定制(见前一篇文章中的描述 ― 请参阅 参考资料),我期望最终在定制方面至少与源代码生成方法具有同样的灵活性。从长远来看,这将使它的适应性比 JAXB 更强。

 

Castor 按照 BSD 样式的许可证进行发布,完全可用于商业用途,而没有什么重大限制。它看起来相当稳定,但每当遇到需要修正错误时,您将需要更新到最新的开发代码(或等待新的 beta 测试发行版)。

 

 

JBind

与 JAXB 和 Castor 类似,JBind 根据 XML 文档的 Schema 描述来生成绑定代码。尽管具有这种相同的性质,但实际上 JBind 的着重点与前两个大不相同。JBind 的主要创建者 Stefan Wachter 称此着重点为“XML 代码”,他是这样描述它的:它将由 Schema 所描述的 XML 数据和由 Java 语言代码所实现的行为组合在了一起。JAXB 和 Castor 更多地着重于使 Java 语言应用程序方便地使用 XML,而 JBind 是围绕 XML 构建应用程序代码框架。一旦 JBind 构建好框架,则可以用自己的代码扩展它来添加功能。

图 5. JBind 生成的类图(单击进行放大) 


 

JBind 还 可以 用于常规的数据绑定,在第 2 部分所讨论的性能测试中,我就是以这种方式用 JBind 的。但这样做略微有点笨拙,部分原因是由于 JBind 总是需要在运行时处理文档的 Schema。如果实例文档不直接引用相应的 Schema,则需要使用特殊的映射文件,或在读取实例文档之前,用手工将正确的 Schema 装入到自己的代码。目前的文档不会真正向您显示这是如何做的。与其它数据绑定框架相比,对处理绑定文档结构的更改,JBind 也很严格。通过使用 ListIterator ,可以删除现有的元素对象,但只有使用生成的 create(创建)方法才能创建新的元素对象,这些方法自动地将这些元素对象添加到现有内容的后面。

 

实质上,JBind 采用与前面框架大不相同的方法来处理文档数据。JBind 不生成 JavaBean 样式的数据类(但 JAXB 和 Castor 是这样做的),而是将一切存储在文档模型(目前为 DOM 级别 2 实现)中,构建绑定代码做为前端(facade)来访问存储在文档模型中的数据。这是一种非常有趣的方法,如果完全实现,这可能具有一些不错的跨范例好处。目前这种方法所具有的唯一好处是在生成代码中 支持基于 XPath 的约束和访问方法。由于存储机制相对于 JBind 的主旨是次要的,因此将来这种机制还可能会有所变动。

 

JBind 所具有的好处是,在考虑过的所有数据绑定框架中,它支持 Schema 最彻底,并且提供 上面 所说的 XPath 扩展。如果应用程序的核心是处理 XML 文档,则使用由 JBind 构造的“XML 代码”框架可能非常简单。对于一般的数据绑定用法,如果应用程序涉及到 XML 文档,而不是其重点时,则其它数据绑定方法可能会更简单些。由于数据分解时需要验证以及由于文档模型后端存储机制(我将在第 2 部分更详细地讲述此问题),因此与其它框架相比,JBind 还存在明显的性能劣势。JBind 是按照 Apache 样式的许可证分发的,完全可用于商业用途。

 

 

Quick

Quick 文档将自身描述为:不是作为处理 XML 的工具,而是作为对使用 XML 的 Java 语言的 扩展 。它基于位于 Java 平台和 XML 之前的一系列开发成果,在此过程中进行了大量的重构工作。它确实为在 Java 平台上使用 XML 提供了非常灵活的框架 ― 它所具有的灵活性远远超出了为写本文我所能够了解和使用到的。

图 6. Quick 生成的类图(单击进行放大) 


 

Quick 的灵活性是有代价的。它使用一系列相当复杂的步骤来根据 DTD 文档描述移到生成的代码,在此过程中使用了作为中间步骤的三个独立的绑定模式(不要与 W3C XML Schema 混淆)文档:

  • QDML 文档提供文档描述,它大致相当于 DTD,不过添加了一些类型和继承。
  • QJML 文档定义了 XML 到 Java 语言对象的绑定。
  • QIML 文件基本上是 QJML 的编译形式,可以用它来生成实际的绑定代码。

在第 2 部分 Quick 的性能测试中,我尽可能少地定制这些文件,但为了得到预期的最终结果,仍然需要做一些手工编辑。根据 DTD 文法生成 QDML 文件之后,必须编辑该文件来定义文档的根元素,并为非 String 值(在这里,是几个 int )添加类型信息。然后,运行程序来从 QDML 生成 QJML 文件,并编辑生成的 QJML,从而向引用添加类型信息。其实,并不真正需要这一步,但有了这一步,就可以用针对对象引用的特定类型生成代码(Castor 和 JAXB 代码生成不支持该特性)。最后,运行该工具以从 QJML 生成 QIML 文件,然后运行代码生成工具完成整个过程,从而获得类 JavaBean 的对象类和实际的绑定类(用来从 XML 转换到 Java 类以及从 Java 类转换到 XML)。

 

再对这些文件进行一些手工编辑,则可以避免生成用于该对象类的新代码,直接链接到 Castor 映射绑定所使用的现有的类。这种可以使用现有类的能力是一项功能非常强大的特性。由于模式文件很复杂,而且为了利用该特性必须做大量的更改,这些因素稍微降低了 Quick 的实用性,但这确实展示了 Quick 的灵活性。

 

灵活性是 Quick 最强大的特性。使用 Quick 的主要缺点是各种模式文件的复杂性,以及缺乏对 Schema 文法的支持。另外,使用 Quick 时,获得帮助看来也很困难:在论坛和邮件列表中,提出的问题常常得不到任何响应。Quick 的许可证遵循 GNU 库(GNU Library)或次通用公共许可证(Lessor General Public License,LGPL),这种许可证允许自由项目和商业项目使用该软件。

 

 

Zeus

象 Quick 一样,Zeus 也根据 XML 文档的 DTD 描述生成代码。(现在正在开发对 Schema 的支持,但目前处在开发的 pre-alpha 阶段)。这两种框架只在这个方面是相似的。Quick 复杂而功能强大,而 Zeus 易于使用 ― 但功能非常有限。

 

图 7. Zeus 生成的类图(单击进行放大) 


 

在用法上,Zeus 代码生成类似于 JAXB 或 Castor,它提供了命令行工具来构造所需要的类。与使用 JAXB 一样,绑定使用接口。JAXB 使用工厂来构造对象类的新实例,而 Zeus 通过原型使用生成的实现类。用 Zeus 可以生成实现类的子类,当对文档进行数据分解时,使用子类而不是使用生成类。

不象前面所讨论过的其它任何框架,Zeus 只支持 String ,而不支持其它类型的值,譬如 intDate 。它还缺乏对引用的支持,所以不能直接进行数据分解或编组图结构。这存在很大的局限性 ― 由于数据绑定可以利用类型数据值和对象间链接的透明处理所提供的便利性,因此这给数据绑定带来许多实用性。没有这些特性的支持,Zeus 更象是一种经过裁减的文档模型,而不象是一个完整的数据绑定框架。

 

如果只使用 String 值,则考虑使用 Zeus 可能是不错的选择。使用 Zeus 的主要缺点是,提供的绑定形式有限,从整体上看,该项目进展缓慢。与使用 Quick 一样,您可能会发现难以找到问题的答案。Zeus 按照 Enhydra 公共许可证 V1.1 进行分发,该许可证来自 Mozilla 公共许可证。

 




回页首


映射绑定 vs. 代码生成

在本文中,我讨论了几种不同的框架,这些框架用于根据 XML 文档文法生成 Java 语言代码。这只是处理用于 Java 语言应用程序的 XML 数据绑定的一种方法。另一种主要方法是使用某种形式的映射绑定方法,在映射绑定方法中,构建自己的类(或者最初根据文法来构建类,然后修改它们以满足您的要求),并向绑定框架指定这些类如何与 XML 文档相关联。每种方法有其利弊,它们都可能有最合适的用武之地。

 

代码生成自动构建反映 XML 文档结构(换句话说,是 DTD 或 Schema 形式的文法)的类,这使您可以非常快速地开始使用文档。当代码生成基于 Schema 描述时,所构造的类可以包括完整的数据类型信息(尽管用此方法存在一些问题;许多 Schema 数据类型在 Java 语言中没有直接对应的数据类型)。用代码生成,您还可以将验证构建进所构造的类中,从而要么自动检查值(当设置好它们时),要么按照需要检查有效性。因此,您可以确保通过编组所生成的文档总是与所期望的结构相匹配。

 

代码生成方法的主要缺点是相对于其优点而言。通过如此贴实地反映文档结构,该方法使应用程序代码和文档结构之间紧密耦合。如果文档结构发生变化,再需要重新生成代码,并修改应用程序代码以使用最终修改后的数据类。

 

通常您还需要使用整个文档结构,为了生成代码,不易于对整个结构划分子集。如果正在使用带有许多可选组件的复杂结构(也许作为业界标准而定义的),而应用程序使用的文档只用这些组件中的某个子集,则这可能会有问题。对于这些框架中的大多数,使用它们时所生成的类将总是与整个文档结构匹配。您可能还需要在运行时包含所有这些生成的类,这取决于所使用的框架。对于应用程序,这导致代码过度膨胀以及数据模型过度复杂。当然,通过编辑 DTD 或者 Schema 以消除不需要的组件,您可以避免这种情况 ― 但随之而来当基本文法发生任何变化时,都需要维护您的修改,这又带来一组新的问题。

 

映射绑定(譬如由 Castor 或 Quick 实现的映射绑定)比代码生成具有更大的灵活性。使用真正的对象类将数据和行为组合在一起。也可以在一定程度上解除对象类与实际 XML 之间的耦合。修改映射定义(而不需要改变应用程序代码)通常处理 XML 文档结构中微小的变化。甚至可以用一种格式定义单独的输入和输出映射来对文档进行数据分解,并用另一种格式编组它们。映射绑定的缺点是,在设置方面,它确实比生成代码方法需要花费更多精力。

 

总之,对于所有应用程序,没有一种方法总是最佳的。如果使用由 Schema 或 DTD 定义的稳定文档结构,并且该结构适合应用程序的需要,则代码生成方法可能是最佳方法。如果使用现有的 Java 语言类,或者希望使用类的结构,该结构反映应用程序对数据用法,而不是 XML 文档结构,则映射方法可能最佳。遗憾的是,当前大多数的开发工作主要集中在代码生成而不是映射。这种局限导致目前只有 Castor 和 Quick 才有这种映射方法。

 




回页首


结束语

在这第 1 部分中,我回顾了几种主要的 XML 数据绑定框架,这些框架支持根据 XML 文档描述生成 Java 语言代码。这些框架在能力方面区别很大(在性能方面亦是如此,我将在第 2 部分中讨论此问题)。在基于 W3C XML Schema 定义的方法中,对于通用的数据绑定应用程序,Castor 提供了当前最佳支持。现在已经可以使用 Castor,目前人们正在扩展它以提供更好的生成代码定制功能和更完善的 Schema 支持。人们还期望 Castor 将来支持即将出现的 JAXB 标准。

 

一旦 JAXB 作为产品发行版使用(当前的 beta 测试版许可证仅允许用于评估),则它看起来将是一项非常吸引人的选择。目前 Castor 似乎比 JAXB 支持更多定制,但 JAXB 将提供可在各实现间进行移植的好处。JAXB 也很可能被用在其它 Java 平台标准(譬如用于 Web 服务的 JAX-RPC 标准)中,所以编写 JAXB 的应用程序在将来可能在插件上兼容这些标准。

 

JBind 提供了最佳的 Schema 支持。如果应用程序适合“XML 代码”模型,并且对性能的需求也不迫切,则 JBind 可能是很好的选择,但对于使用一般的 XML 数据绑定,它显得比较笨拙。Quick 提供了非常大的灵活性且功能强大,但它只支持 DTD 文法,而且使用起来相当复杂。Zeus 简单且容易,但它(与 Quick 一样)只支持 DTD,另外,只允许访问作为 String 值的数据。

 

最后三个框架似乎更适合具有特殊需求的应用程序,而非一般用途。如果文档只有 DTD 描述,而没有模式,则出于这个原因,您可能希望尝试 Quick 或 Zeus。对于大多数应用程序,这不是主要关心的问题,因为有许多可用于将 DTD 转换到模式的应用程序(尽管可能需要一些手工调整)。在 Castor 分发版中包括了一个这样的程序(正如在 Castor XML FAQ 中所提到的, org.exolab.castor.xml.dtd.Converter )。

 

在第 2 部分中,我将展示这些数据绑定框架的性能结果,这些性能是在一些样本文档上使用这些框架测试出的。这些结果涉及了生成代码方法和映射绑定方法,为了进行比较,包含了文档模型。我确实惊讶地看到……,但等等,现在我不能把 一切都告诉您。另外提醒您,在下个星期别错过这个完全关于性能的“故事” ― 我保证您会找到值得一读的结果!

您可以参阅本文在 developerWorks 全球站点上的 英文原文.

  • 请参与本文的 论坛。(您也可以单击本文顶部或底部的 讨论来访问该论坛)。

  • 如果要了解有关 XML 的背景知识,请尝试参加 developerWorks教程 XML 入门(2002 年 8 月)。

  • 阅读作者以前的文章“ 用 Castor 进行数据绑定”,这篇文章讲述了 Castor 的映射数据绑定技术( developerWorks,2002 年 4 月)。

  • 浏览作者以前的 developerWorks文章, 性能(2001 年 9 月)和 用法(2002 年 2 月),这两篇文章比较了几种 Java XML 文档模型。

  • 阅读 Brett McLaughlin 的文章“ Converting between Java objects and XML with Quick”,该文概述了 Quick,并向您展示了如何使用该框架来快速方便地将 Java 数据转换成 XML 文档,而不需要其它数据绑定框架所需的类生成语义( developerWorks,2002 年 8 月)。


  • 有关对象关系数据绑定的基础知识简介,请阅读“ Getting started with Castor JDO”一文(由 Bruce Snyder 撰写, developerWorks,2002 年 8 月)。

数据绑定框架

  • 查找更多有关 Java Architecture for XML Binding (JAXB)方面的内容,JAXB 是一个处于正在发展中的 Java 平台数据绑定标准。


  • 更进一步了解 Castor框架,它支持映射绑定和生成绑定。


  • 了解 JBind,它主要偏重于围绕 XML 构建应用程序代码框架,不太注重使 Java 语言应用程序方便地使用 XML。

  • Quick 框架是基于 Java 平台和 XML 出现之前的一系列开发成果。它为在 Java 平台上使用 XML 提供了极其灵活的框架。

  • 研究 Zeus的方方面面,它(类似于 Quick)根据 XML 文档的 DTD 描述来生成代码,使用 Zeus 要比使用 Quick 简单,但同时 Zeus 要更有限。

其它链接

分享到:
评论

相关推荐

    用JAXB生成一个XML

    Java XML绑定架构(JAXB)提供了一个绑定编译器,xjc,来从一个XML模式中生成Java类。用JAXB的xjc生成的Java类代表了在XML模式中不同的元素和复杂类型(complexType)。(一个复杂类型通过指定属性和元素内的元素来提供对...

    JAXB完成XML和Java对象的互转

    该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用...

    Java and XML, 3rd Edition

    全面讲解了SAX、DOM、StAX、JDOM以及dom4j的应用程序编程接口,同时还囊括了最新版本的用于XML处理的Java应用程序编程接口(JAXP)和用于XML绑定的Java架构(JAXB)的相关知识。第三版还彻底重写了有关网络技术的...

    JAVA与XML.rar

    全面讲解了SAX、DOM、StAX、JDOM以及dom4j的应用程序编程接口,同时还囊括了最新版本的用于XML处理的Java应用程序编程接口(JAXP)和用于XML绑定的Java架构(JAXB)相关知识。第三版还彻底重写了有关网络技术的章节,...

    maxb:XML绑定移动体系结构(MAXB)为IOS Objective-C和基于JAXB XJC的Android Java绑定编译器提供了XSD

    XML绑定移动体系结构(MAXB)为IOS Objective-C和基于JAXB XJC的Android Java绑定编译器提供了XSD。 ##注意MAXB最初是的fork。 (及相关项目: , 和 )是由开发的,2013年起一直保留。由于设计和实施都非常好,...

    Java与XML第三版本

    包括核心接口和XPath支持 StAX应用程序编程接口,包括StAX的工厂方法(factory)、文档生成和XMLPull 使用JAXB进行数据绑定,使用新的JAXB 2.0 annotation 使用RSS进行网络同步和podcasting 表示层的XML应用,...

    返利网java源码-jaxb:用于XML绑定类的Java架构的JRuby脚本

    生成的代码支持,提供了从各种来源解组文档以及将内容树编组到各种目的地的方法。 JAXB 还支持 SAX(XML 的简单 API)的编组和解组。 (来自 JAXB 教程) JAXB 使用 Java 的注解为生成的类增加附加信息,这些附加...

    jaxb-format-plugin:JAXB(用于XML绑定的Java API)架构到源代码编译器(XJC)的插件,该代码生成代码以通过XPath表达式格式化生成的类的实例-Form source code

    用于JAXB(用于XML绑定的Java API)架构到源代码的编译器(XJC)的插件,该代码生成代码以通过任意帮助程序类格式化生成的类的实例。 动机 XJC当前有多个插件,可以在生成的JAXB类文件中生成“ toString()”方法。...

    JAVA_API1.6文档(中文)

    java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的...

    JAXB2_20080829.jar

    JAXB2_20080829.jar (JAXB)是一...JAXB提供了一种快速和方便的方式来将一个XML模式绑定到Java代码的一个表示上,使得Java开发者能够更轻松地将XML数据和Java应用中的处理函数融合在一起,而不必对XML本身有很多的了解。

    castor R/M映射神器

    它可以在java对象、XML文本、SQL数据表以及LDAP目录之间绑定。Castor几乎是JAXB的替代品。Castor是ExoLab Group下面的一个开放源代码的项目,它主要实现的是O/R映射功能。它主要API和数据接口为:JDO-like, SQL, OQL...

    wiseml-java:WiseML 的 JAXB 绑定

    WiseML 的 JAXB 绑定 建造 无需安装。 要构建它,您需要 Java 6 或更高版本以及 2.0 或更高版本。 在克隆此存储库之前,请确保使用“git config --global core.autocrlf input”在您的机器上启用 CRLF/LF 的自动...

    JiBx开发入门指南

    JiBx又一个不错的xml绑定工具,和jaxb等一样,都是属于xml绑定工具。而JiBx使用java字节码enhance技术,不像jaxb等更多在于源代码生成技术。JiB的工作主要在于前期,也就是进行字节码绑定,这一部分基本上都是在...

    3种xml解析方法

    共3篇第一篇:用JAXB实现JAVA对象与XML文件的绑定 第二篇:程序设计用JAXB生成一个XML文档 第三篇:dom4jxml文件解析

    dsl4xml:通过镜像文档结构的DSL轻松快速地将XML和JSON编组为Java对象

    JAXB和其他xml绑定工具和框架可能需要依赖大型库或其他编译时步骤。 dsl4xml的灵感来自于最近的一些工作,这些工作加快并提高了Android应用程序中某些复杂(缓慢)的XML解析代码的可读性。 JSON解析现在可以尝试...

    Java 1.6 API 中文 New

    java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的...

    JavaAPI1.6中文chm文档 part1

    java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的...

    java8看不到源码-java-stix:STIX的Java绑定

    java8 看不到源码java-stix STIX 的 Java 绑定,结构化威胁信息表达语言,用于表示结构化网络威胁信息。 java-stix正在官方下开发。 概述 java-stix 的一个主要目标是忠实于结构化威胁信息表达 (STIX:trade_mark:) ...

    xjc-gradle-plugin:一个Gradle插件,用于运行XJC绑定编译器以从XSD架构生成JAXB Java源代码

    一个Gradle插件,用于运行XJC绑定编译器,以使用JAXB从XML模式(xsd文件)生成Java源代码。 要求和功能 该插件需要Gradle 5.6或更高版本。 它已通过Java 8和Java 12进行了测试。 它支持XJC版本2.3.2和更高版本...

    java api最新7.0

    java.nio 定义作为数据容器的缓冲区,并提供其他 NIO 包的概述。 java.nio.channels 定义了各种通道,这些通道表示到能够执行 I/O 操作的实体(如文件和套接字)的连接;定义了用于多路复用的、非阻塞 I/O 操作的...

Global site tag (gtag.js) - Google Analytics