XML与java文档格式.docx

上传人:b****6 文档编号:17069035 上传时间:2022-11-28 格式:DOCX 页数:58 大小:209.67KB
下载 相关 举报
XML与java文档格式.docx_第1页
第1页 / 共58页
XML与java文档格式.docx_第2页
第2页 / 共58页
XML与java文档格式.docx_第3页
第3页 / 共58页
XML与java文档格式.docx_第4页
第4页 / 共58页
XML与java文档格式.docx_第5页
第5页 / 共58页
点击查看更多>>
下载资源
资源描述

XML与java文档格式.docx

《XML与java文档格式.docx》由会员分享,可在线阅读,更多相关《XML与java文档格式.docx(58页珍藏版)》请在冰豆网上搜索。

XML与java文档格式.docx

去年,我写了一篇文章,讲述了如何使用Castor框架以进行Java对象到XML文档的映射数据绑定。

我曾经答应要写一篇后续文章,其中将探讨代码生成方法,包括介绍JAXB,JavaCommunityProcess(JCP)正在开发JAXB,它是用Java语言编写的、用于数据绑定的标准API。

就在较早的那篇文章发布不久,Sun宣布对JAXB的方向做出了重大调整(请参阅重新架构JAXB)。

由于这方面的变化,所以我想,为了更贴近最终的JAXB代码,最好先不写这篇后续文章,现在,我很高兴,终于可以写这篇文章了!

数据绑定字典

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

文法(Grammar)是用于定义一系列XML文档结构的一套规则。

其中一类文法是XML规范所定义的文档类型定义(DocumentTypeDefinition,DTD)格式。

另一类日渐普及的文法是XMLSchema规范所定义的W3CXMLSchema(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.样本文档

<

?

xmlversion="

1.0"

>

timetable>

<

carrierident="

AR"

rating>

9<

/rating>

URL>

/URL>

name>

ArcticAirlines<

/name>

/carrier>

CA"

7<

CombinedAirlines<

airportident="

SEA"

location>

Seattle,WA<

/location>

Seattle-TacomaInternationalAirport<

/airport>

LAX"

LosAngeles,CA<

LosAngelesInternationalAirport<

routefrom="

to="

flightcarrier="

number>

426<

/number>

depart>

6:

23a<

/depart>

arrive>

8:

42a<

/arrive>

/flight>

833<

10a<

10:

52a<

433<

9:

00a<

11:

36a<

/route>

311<

7:

45a<

20a<

593<

27a<

12:

04p<

102<

30p<

3:

07p<

/timetable>

图1显示了用于映射数据绑定到这些文档的类结构。

为了进行比较,我将在有关各个数据绑定框架章节中显示生成的类结构。

这里包含的这些图仅仅是所有情况的缩略图;

如果要看全图,请单击这个小图像。

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

JAXB面前的漫漫长路

用于XML绑定的JavaAPI(JavaAPIforXMLBinding,JAXB)是一个处于不断发展中的Java平台数据绑定标准。

JavaCommunityProcess正在开发作为“JSR-31―XML数据绑定规范(XMLDataBindingSpecification)”的JAXB。

该项目始于1999年8月,其目的是定义一种方法,生成与XML结构相链接的Java语言代码。

最初打算在2000年第2季度发布,但最后在JavaOne2001上宣布了初步的EarlyAccess(EA)版本,该版本在2001年6月向公众发布。

JAXB的EA版本基于具有创新意义的拉解析器(pullparser)设计,这种设计使验证可以方便地构建到生成的数据分解代码中。

它根据DTD生成代码,构建在解析XML文档时自动验证XML文档结构(而不是数据)的类。

我们期望这种方法能快速和有效地处理XML和Java语言对象之间的转换,但EA代码仅仅是部分实现,显然在成为完整的实现之前,仍需要做大量工作。

专家组不久之后开始收到关于EA发行版的反馈。

作为对反馈意见的部分响应中,他们研究决定重新架构JAXB,之后更新了网站,声明JAXB在几个方面正在得到增强。

该站点还声明,下一版本在API级上不与早期版本兼容―但您仍然可以下载EA版本。

重新架构JAXB

直到2002年3月,新体系结构的细节才公布于众,在JavaOne上,Sun宣布,作为在JAXB方面进一步工作的基础,实际上正在放弃EA代码。

它将被新设计所替代,在新设计中,共享了一些常见的功能,但新设计使用不兼容的API和内部体系结构。

发展方向变化如此之大,让我和那些对EA代码有兴趣的人们感到惊讶。

JAXB项目的SUNJSR负责人JosephFialli把这么大的变化归结为以下一些因素。

主要问题是扩展原有代码库以支持W3CXMLSchema的复杂性。

这是一个相当复杂的规范,以至于在批准之后的两年多时间里,在所有平台上,仍然只有少数几个解析器能接近完全符合规范。

最初的JAXB代码需要实际对象来控制验证,而且将这种方法扩展到Schema将耗费太多精力,以至于在合理的期限内无法实现这项工作。

为适应Schema而做出变更的同时,专家组还决定重新考虑处理验证的方法。

原来的JAXB代码无条件地验证文档的结构,如果发现错误,则抛出异常并中止处理。

Fialli说,在公众的意见中,抱怨这种方法局限性太大、限制太严―在一些情况下,用户希望能够一次检查多个验证错误,而在另一些情况下,则希望完全禁用验证(或者由于性能原因,或者在编组没有精确匹配文法的文档时)。

新的JAXB体系结构能够满足这两种需求。

最后,专家组决定放弃单个绑定框架运行时(就象在原来EA发行版中所看的)的想法。

而采用接口方法,其实质是可以使用不同的数据绑定框架。

这使用户代码可以在各框架之间进行移植,而不需移植生成的类―这些类特定于专门的数据绑定框架,它们只能由该框架运行。

强制性的SAX2.0解析器支持替代了EA运行时中所使用的拉解析器方法,对于其它解析器(可能包括新的拉解析器,该解析器基于用于XML的流式API,JSR173正在定义此API),提供可选的特定于框架的支持,数据结构本身被更改为类JavaBean的数据对象,外部框架可以方便地操作此数据对象。

JAXBbeta测试版

自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语言代码绑定到W3CXMLSchema文法所定义的文档。

由于有可能批准将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的主要创建者StefanWachter称此着重点为“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文档描述移到生成的代码,在此过程中使用了作为中间步骤的三个独立的绑定模式(不要与W3CXMLSchema混淆)文档:

∙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映射绑定所使用的现有的类。

这种可以使用现有类的能力是一项功能非常强大的特性。

由于模式文件很复杂,而且为了利用该特性必须做大量的更

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 政史地

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1