`

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 要更有限。

其它链接

分享到:
评论

相关推荐

    Java与XML数据绑定

    Java与XML数据绑定是将XML文档中的数据结构映射到Java对象的过程,反之亦然。这一技术使得在Java应用程序中处理XML数据变得更加便捷,避免了手动解析和构建XML字符串的繁琐工作。本篇将深入探讨Java中XML数据绑定的...

    JAVA和XML数据绑定 经典PDF

    Java和XML数据绑定是将XML文档中的数据与Java对象模型之间建立映射关系的技术,使得开发者可以方便地在XML和Java对象之间进行数据交换。这项技术对于处理XML数据的Java应用来说至关重要,尤其是在Web服务、配置文件...

    Java XML绑定技术 (Castor JAXB XMLBeans)

    JAXB(Java Architecture for XML Binding)是Sun Microsystems(现已被Oracle收购)推出的一种Java XML绑定框架。它是Java EE标准的一部分,提供了一种机制来将Java对象与XML文档相互转换。使用JAXB,可以通过简单...

    xml和java绑定

    11. **SOAP与Web服务**: 在Web服务中,XML作为数据交换的标准,Java通过JAX-WS(Java API for XML Web Services)与XML绑定,实现了SOAP消息的处理。 12. **RESTful服务**: 对于RESTful服务,虽然JSON更为常见,但...

    JAXB 利用xsd文件生成java类

    JAXB (Java Architecture for XML Binding) 是Java平台上的一个标准,用于将XML文档与Java对象之间进行绑定,实现XML数据的解析和序列化。在Java开发中,JAXB提供了一种方便的方式,允许开发者通过XML Schema (XSD) ...

    JAXB 生成XML文件

    在Java应用程序中,JAXB使得处理XML数据变得更加便捷,无需编写大量手动转换代码。 JAXB的核心概念包括以下几点: 1. **数据绑定**:JAXB提供了一种机制,可以将Java类和XML Schema定义之间的映射关系自动创建。这...

    jaxb生成XML例子

    JAXB (Java Architecture for XML Binding) 是 Java 中用于对象到XML以及XML到对象转换的API。它使得开发者能够轻松地将Java对象模型映射到XML文档,并反之亦然。在给定的例子中,我们将深入理解如何使用JAXB注解来...

    通过JAXB实现完成java对象和xml的互相转换

    JAXB的另一个重要特性是它支持XML绑定的定制,包括命名空间处理、类型转换、列表处理等。开发者可以通过实现`XmlAdapter`接口来自定义数据类型的转换。 总的来说,JAXB为Java开发者提供了一种强大且灵活的方式,...

    JAXB的安装包及插件

    JAXB提供了一种声明式的方法来处理XML,通过注解或XML绑定元数据来定义Java类和XML元素之间的映射关系。 **安装JAXB** 安装JAXB通常分为两个步骤:添加JAXB库和(可选)安装相关的IDE插件。 1. **添加JAXB库**:...

    java生成xsd,xml示例

    2. 创建JAXB上下文:使用`JAXBContext`实例化,该类能够将Java类与XML绑定。 3. 创建Marshaller:使用`JAXBContext`创建`Marshaller`,用于将Java对象转换为XML。 4. 将Java对象转换为XML:调用`Marshaller.marshal...

    JAXB_Java Architecture For XML Binding

    Java Architecture for XML Binding (JAXB) 是Java平台上的一个标准技术,它允许程序开发者将XML文档与Java对象之间进行绑定,实现XML数据的序列化和反序列化。JAXB是Java SE和Java EE环境中的一部分,提供了高效且...

    webservice之使用jaxb把xml转换Object或把对象转换成xml文件

    在Java世界中,使用JAXB(Java Architecture for XML Binding)库可以方便地实现XML数据与Java对象之间的转换,从而在WebService中轻松处理数据交换。本篇文章将深入探讨如何使用JAXB进行XML到Object以及Object到XML...

    使用jaxb根据xsd生成xml文档

    在Java开发中,XML文档的生成与解析是一项常见的任务,特别是在处理数据交换和存储时。JAXB(Java Architecture for XML Binding)是Java平台标准的一部分,它提供了一种将Java对象转换为XML文档以及从XML数据恢复...

    java根据xml生成schema_xsd_生成javabean

    在Java中,JAXB实现了XML数据绑定,使得XML文档和Java对象之间的转换变得简单和直观。生成的JavaBean可以直接用来填充或读取XML文档,简化了开发工作。 5. JavaBean规范:JavaBean必须满足一些基本要求,如拥有公共...

    利用JAXB进行xml和javabean之间转换

    JAXB通过元数据(如注解或XML绑定文件)来映射Java类到XML元素,以及XML元素到Java类。这使得XML文档能够被自动解析成Java对象,反之亦然。 **1. JAXB的使用步骤** (1) **创建Java类(javabean)** 首先,定义一...

    idea 中用jaxb 读xml中数据

    2. **生成JAXB绑定类**:Idea提供了一个便捷的功能,可以自动生成JAXB绑定类。只需右键点击项目,选择"Generate" -&gt; " JAXB Classes",然后导入XML文件。这将根据XML文件结构生成对应的Java类。 3. **创建...

Global site tag (gtag.js) - Google Analytics