Java开发网 Java开发网
注册 | 登录 | 帮助 | 搜索 | 排行榜 | 发帖统计  

您没有登录

» Java开发网 » 技术文章库  

按打印兼容模式打印这个话题 打印话题    把这个话题寄给朋友 寄给朋友    该主题的所有更新都将Email到你的邮箱 订阅主题
flat modethreaded modego to previous topicgo to next topicgo to back
作者 Zeus实现XML-JAVA的数据绑定
palatum



CJSDN高级会员


发贴: 451
积分: 80
于 2003-03-21 17:28 user profilesend a private message to usersend email to palatumsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Zeus实现XML-JAVA的数据绑定

钟家豪 (judson78@yahoo.com.cn)

2003 年 3 月

Zeus可以将JAVA对象与XML文件进行绑定,绑定使数据在J2EE中的应用更加方便。本文主要介绍Zeus的编译与使用。对绑定过程中使用的DTD和XML文件也有说明。
1 ZEUS简介
Enhydra是以生长于美国加利福尼亚海边的小水獭命名的非营利组织的名字。从但与著名的Apache不同,Enhydra致力于围绕Application Server的电子商务解决方案的研究。Zeus就是Enhydra开发的众多的工具软件中的一个,功能是对JavaObject和XML进行数据绑定。它可以将任意的XML文件转化为对应的JavaObject文件,并且将数据方便的在这两种形式之间转换。Zeus最新版本是Zeus1.0 Beta 3.5,由于是完全的源码开放,可以到 http://zeus.enhydra.org/software/downloads/index.html 下载源代码后自己编译。

2 预备知识

2.1 用XML作为数据载体
XML(Extensible Markup Language)由W3C组织制定并得到世界上几乎所有大公司的支持。XML是一种非常灵活的文本格式,与HTML相比,XML延续了其简单、易懂的语法,但是却有了更大的灵活性和扩展能力。例1是一段描述Customer信息的XML文件,作为描述数据的语言,XML的组织形式很自由且表述清晰。

<?xml version="1.0" encoding="GBK"?>
<Customer Customer_No= "00001">
< Name>李俊</ Name>
<Id_No>210106421016001</Id_No>
<Sex >男</Sex>
<Birth_Place>大连</Birth_Place>
<Birth_Date>1942-10-16</Birth_Date>
<Nationality>中国</Nationality>
<Education>高中</Education>
<Address>大连市沙河口</Address>
<Contact_Info Id = "00001">
<Zip_Code>116001</Zip_Code>
<Tel_No>2645677</Tel_No>
</Contact_Info>
</Customer>



例1:描述Customer的XML文件

这段XML结构很清晰:描述的是一个"顾客"实体,这个实体有其属性:姓名、身份证号、性别、出生地、生日、出生地、联系方式(邮编、电话)等。

第一行<?xml version="1.0" encoding="GBK"?>表述此XML文件的版本是1.0,用的是"GBK"的编码方式(如果要解析中文,GBK或GB2312是必须的)。<Customer Customer_No= "00001></Customer>组成该文件完整的"根标记",Customer_No是Customer标记的"属性",<Name></Name>、<Nationality></Nationality>是<Customer>的子标记。而在< Contact></Contact>中还可以继续包含子标记:<Zip_Code>、<Tel_No>。用户自定义tag的XML语言给了用户足够的自由度表示数据,但是也为显示和解析带来了难度,为了解决这一问题,W3C在格式控制和标记定义上对XML加以限制。例如<customer></Customer>就是一对不合格的标记。

2.2 DTD定义数据
DTD(Document Type Definition)目的是定义XML文档中的元素和各元素间的关系。DTD可以与应用它的XML共存在一个文件中,也可以单独成为一个文件。例2是一个描述例1所述的xml文件的DTD文件。

<?xml version="1.0" encoding="GBK"?>
<!ELEMENT Customer (Name?,Id_No?,Sex?,Birth_Place?,Birth_Date?,Nationality?, Education?, Contact_Info?>
<!ATTLIST Customer
Customer_No CDATA #REQUIRED
>
<!ELEMENT Name (#PCDATA)>
<!ELEMENT Id_No (#PCDATA)>
<!ELEMENT Sex (#PCDATA)>
<!ELEMENT Birth_Place (#PCDATA)>
<!ELEMENT Birth_Date (#PCDATA)>
<!ELEMENT Nationality (#PCDATA)>
<!ELEMENT Education (#PCDATA)>
<!ELEMENT Contact_Info (Zip_Code?,Tel_No?)>
<!ATTLIST Contact_Info
id CDATA #REQUIRED
>
<!ELEMENT Zip_Code (#PCDATA)>
<!ELEMENT Tel_No (#PCDATA)>



例2:DTD文件

无规矩不成方圆,例2的DTD文件定义了例1的XML描述的Customer元素,通过DTD的定义,XML中的标记都被赋予了意义,并且很好的解释了Customer与其它元素之间的关系。DTD文件的存在使XML中的数据有了规定的形式,二者由如此紧密地联系容易联想到另外一种重要的数据组织方式--数据库的表中的字段和数据。DTD-XML这种与表结构-数据类似的结构为这两种技术的相互转换提供了天然的方便条件,借助于DTD,可以方便的将表中的数据用XML表示。

3 编译你的Zeus
下载下来的Zeus是一个zip文件,如果选择的是源代码下载,就必须首先编译才能够使用。本文介绍zeus的使用,首先从源代码的编译说起。

编译的方法在下载的docs文件夹中有详尽的描述,作为Java技术阵营的一份子,Zeus在将自己完全奉献的同时也使用了其他的一些杰出的Java工具。比如编译就使用了Apache的Ant。可以在Zeus\lib下找到Ant.jar文件。

在编译之前唯一要做的事就是设定好操作系统的JAVA_HOME环境变量。例如在windows系统,如果jdk安装在D:/jdk1.3.1,则运行set JAVA_HOME = D:/jdk1.3.1。完成了准备工作就可以开始编译zeus,Ant本身是易于使用的编译工具,build.xml文件可以设定所有编译的细节和文件的组装。Zeus的编译文件位于根目录下的build.xml,这个XML文件包含了对Zeus编译并组装zeus.jar文件的一切细节而且有很高的可读性。

确定在zeus的根目录下,运行./bin/build.bat targets,Ant可以找到位于当前目录下的build.xml文件,如果不输入任何参数,ant会输出提示要你输入编译targets:

compile:编译zeus的所有源代码,并将之放置于build\classes下;
bin:将原src\bin下的文件拷到build\bin下,原lib目录下的jar文件拷到build\lib下并将组合好的zeus.jar置于此文件夹下;
doc:编译javadoc,并将结果拷到bin\docs\apidoc\下。

sample和test分别用于编译例程和测试代码。如果不想一步一步编译,可以将targers参数设为all,这样ant就会以正确的次序为你自动编译好所有的targets。编译后的会出现一个build文件夹,所有编译好的文件都在这个文件中。检查build/bin文件夹,出现的Zeus.jar文件就是编译好的工具。如果你有足够的经验去修改Zeus的源代码和build.xml文件,完全可以打造属于你自己的Zeus。

4 生成描述XML的Java对象
生成Java对象的第一步是使用Zeus自动生成Java源代码。使用zeus的批处理文件在build\bin\的zeus.bat,使用语法如下:

zeus.bat -constraints=
[-outputDir=]
[-collapseSimpleElements=]
[-ignoreIDAttributes=]
[-javaPackage=]
[-root=]

参数解释如下:

参数 必须 默认值 描 述
Constraints Yes 无 指定产生java代码的约束文件(dtd或xsd.文件)
OutputDir No 当前目录 放置生成java文件的根目录
CollapseSimpleElements No False 是否支持简单元素的精简,所谓"简单元素"就是在DTD文件中描述的没有属性(attribute)的元素(Element)。如果这样的简单元素以"精简"形式被Zeus解析,则生成的Java类使用其父元素的get[ElementName]()的形式来得到XML中该元素的值,这种形式比普通的get[ElementName]().getContent()的形式更简便。而且减少了很多不必要的生成类。
IgnoreIDAttributes No False 此参数设定判断"简单元素"的条件:是否将ID属性作为条件。设定此参数为true会导致那些只有一个"id"属性的元素被看作是"简单元素"
JavaPackage No 无 指定生成的java类的包。例如:指定com.zjh.tools后,所有生成的java类都在com.zjh.tools包内。
Root No 由DTD解析器决定 确定用于解析的根元素。解析有多个顶级元素的DTD文件时,指定根元素使之生成正确的java类。

继续上面的例子,将例1的XML文件与Java Objects绑定,第一步要生成Java文件,具体方案就是使用Zeus.jar中的org.enhydra.zeus.util.DTDSourceGenerator,例2中的Customer.dtd文件作为必须的constrains参数。首先执行下列命令:

将Customer文件置于c:\zeus\dtd文件下,建立c:\zeus\zjhsample,执行下列命令:
C:\zeus>.\build\bin\zeus.bat -constraints=dtd\Customer.dtd -outputDir=zjhsample -javaPackage =com.zjh.zeustest.binding -collapseSimpleElements=true

查看c:\zeus\zjhsample\com\zjh\zeustest\binding文件夹,发现生成了六个文件:Customer.java、CustomerImpl.java、Contact_Info.java、Contact_InfoImpl.java、CustomerUnmarshaller.java、Unmarshallable.java。

生成的类名有规可循:Customer、Contact_info是DTD文件中非简单元素的名称,Zeus生成与其同名的接口;CustomerImpl、Contact_infoImpl是实现这两个接口的类。CustomerUnmarshaller与Unmarshallable看起来有些奇怪,但也不是凭空而来:Unmarshallable接口继承自org.xml.sax.ContentHandler,提供解析XML合法性的接口,所有的ElementImpl类都要继承该接口;CustomerUnmarshaller提供反解码XML的接口,将XML文件输入,返回Customer对象。

数据绑定的所有秘密都隐藏在这几个文件中,可以用任何的文本编辑器对其进行编辑。但是就像程序声明所述:修改这些程序也许会导致数据绑定操作的失败。

最后编译这六个java文件:javac *.java,生成class文件。这样,就得到了用于描述XML文件的Java类。

5 Marshal与Unmarshal--XML与JAVA Object的转换
通用的XML文件适合不同技术平台之间的数据传输,Java对象可以为Java程序提供更加方便的使用接口,通过Zeus工具生成的Java Object就像是一座桥梁,将二者紧密地联系在一起(见图1)。它不仅在内部构建了足够的用来描述XML文件各个元素值的属性,更提供了可以将Java对象与XML文件相互转化的接口:Unmarshal和Marshal。

Unmarshal:将XML文件"反解码"为JavaObject;

Marshal:将JavaObject"解码"为XML文件。

图1:Java对象与XML文件的转换

5.1 Unmarshal XML文件到Java对象
一旦用Zeus生成的Java对象被编译,将XML文件转化为Java形式的表述就变成了一件简单且惬意的事。这一过程被描述为"反解码(Unmarshal)",其实它是Zeus根据DTD文件生成的ElementImp对象的Unmarshal()方法。如同科幻小说中的物品自动制造机,向Unmarshal方法投入以Java File、Writer、或InputStream形式包装的XML文件,一按Unmarshal按钮,XML数据的Java表示版就轻而易举的诞生了。示例程序(例3)中的CustomerUnmarshal类完成了Unmarshal例1中customerInfo.xml的工作,并把结果输出到屏幕上。

package com.zjh.zeustest;
import java.io.*;
import com.zjh.zeustest.binding.*;

public class CustomerInfo {
public static void main(String[] args) {
if(args.length!=1){
System.out.println("please in put the location of XML file");
return;
}
try{
Customer customer = CustomerUnmarshaller.unmarshal((new File(args[0])),false);
System.out.println("姓名:"+customer.getName());
System.out.println("证件号码:"+customer.getId_No());
System.out.println("性别:"+customer.getSex());
System.out.println("出生地:"+customer.getBirth_Place());
System.out.println("国籍:"+customer.getNationality());
System.out.println("学历:"+customer.getEducation());
System.out.println("邮政编码:"+customer.getContact_Info().getZip_Code());
System.out.println("电话号码:"+customer.getContact_Info().getTel_No());
}catch(Exception e){
e.printStackTrace();
}
}
}



例3 Unmarshal XML

编译该程序后用下列命令运行:
java -classpath .\;..\lib\xerces.jar com.zjh.zeustest.Customer Unmarshal ..\cust.xml

输入如下:

姓名:李俊
证件号码:210106421016001
性别:男
出生地:大连

国籍:中 国
学历:高 中
邮政编码:116001
电话号码:2645677



5.2 Marshal Java对象到XML文件
把数据从Java Object的形式转换为XML文件是Unmarshal的逆过程,在语义上用的也是Marshal(解码)这一名词。下面提供的例子(例4)提供一个数据绑定使用完整的例子:

将Cust.xml读入
Unmarshal XML
修改Java对象的属性值
Marshal Java对象

package com.zjh.zeustest;
import java.io.*;
import com.zjh.zeustest.binding.*;

public class CustomerMarshal {

public static void main(String[] args) {
if(args.length!=1){
System.out.println("please in put the location of XML file");
return;
}
try{
Customer customer = CustomerUnmarshaller.unmarshal((new File(args[0])),false);
Contact_Info contactInfo = customer.getContact_Info();
contactInfo.setId("0002");
contactInfo.setZip_Code("116001");
contactInfo.setTel_No("6656456");
customer.setBirth_Date("1979-10-1");
customer.setBirth_Place("大连");
customer.setContact_Info(contactInfo);
customer.setCustomer_No("1234566");
customer.setEducation("大学");
customer.setId_No("210204197910012233");
customer.setName("李明");
customer.setNationality("中国");
customer.setSex("男");
customer.marshal((new File("MarshalCust.xml")));
}catch(Exception e){
e.printStackTrace();
}
}
}


例4 Marshal JavaObject

执行该程序后生成的新的MarshalCust.xml如下所示:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE Customer SYSTEM "D:\zeus\dtd\Customer.dtd">
<Customer Customer_No="1234566">
<Name>李明</Name>
<Id_No>210204197910012233</Id_No>
<Sex>男</Sex>
<Birth_Place>大连</Birth_Place>
<Birth_Date>1979-10-1</Birth_Date>
<Nationality>中国</Nationality>
<Education>大学</Education>
<Contact_Info id="0002">
<Zip_Code>116001</Zip_Code>
<Tel_No>6656456</Tel_No>
</Contact_Info>
</Customer>



选择Zeus的理由与思考:
Java与XML是一对天生的兄弟,在所有计算机软件技术都高举XML大旗的时候,有一万个理由实现Java与XML的完美结合。Sun、Apache也提供了功能强大XML解析包,站在巨人的肩膀上(实际上Zeus使用了Apache的Xerces来解析XML),Zeus提出的是数据绑定的概念。

从解析到绑定不需要很复杂的实现手法,但却提供给使用者更加简单和灵活的解决方案。编程技术的发展和开放软件的出现为创意提供了更广阔的空间,选择Zeus,使用Zeus,思考Zeus--没有复杂的技术,只有令人赞叹的创意。这也许就是后软件时代程序生存的真谛,我想。



作者 Re:Zeus实现XML-JAVA的数据绑定 [Re:palatum]
palatum



CJSDN高级会员


发贴: 451
积分: 80
于 2003-03-21 17:30 user profilesend a private message to usersend email to palatumsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
图1



作者 Re:Zeus实现XML-JAVA的数据绑定 [Re:palatum]
Julian13





发贴: 387
积分: 52
于 2003-03-21 17:51 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
选择Zeus的理由与思考:
...
Java与XML是一对天生的兄弟,在所有计算机软件技术都高举XML大旗的时候,有一万个理由实现Java与XML的完美结合。
...


thx and it look very handy. just wonder any major different from Castor.
also, seem Zeus treat all value as String; could i specify the target data type? might be time to read manual again :>

BTW, really want to see the 10 thousand reasons (a joke only). Tongue



作者 Re:Zeus实现XML-JAVA的数据绑定 [Re:palatum]
MrTong



发贴: 0
积分: 0
于 2003-03-22 09:09 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
哈哈,我做研究的项目就是和zeus有关的哪,我以为zeus是很偏僻的东西原来斑竹也知道啊Smile


作者 Re:Zeus实现XML-JAVA的数据绑定 [Re:palatum]
ftang



版主


发贴: 214
积分: 38
于 2003-04-19 10:15 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Actually, Zeus is not the only java, xml binding tools on market right now,
sun have a project called jaxb, also did same thing...
I evaluated these two tools in my last project, but actually I don't think the automatical binding tool is a trade off, architech VS performance, when you use the xml, if you are not using every nodes in the xml, and the xml u receive is pretty long, then you should not use any java xml binding tools, because

first, when you use the Zeus or jaxb, the tool will generate all the object from the xml no matter you need or not---tons of garbage right there--you will never use them, how you gonna explain these things to your project manager--at least I will not take these shit in my project we will never use...

second, when parse the xml in application...the binding tools is not that fast, we can understand why is not fast because after load the xml into DOM object, you will marshall again to another object model the tools create before, so if you have B2B enterprise stucture, then you retrieve XML through http realtime, you should concern performance.

third, very difficult to upgrade...xml data if we consider as database table, they will not keep same forever, sometime they even change frueqently than we think, if you use binding tools, then every time the xml format change---even include the schema and DTD change, you have to run the tools again and suck the new classes file back to the jar, even you still read old data don't care the new change...you still have to do that....what a nightmare, maybe you cann't image, but the stuff I talked about is from the real time exp...

if anyone want to know more about jaxb or zeus, contact me at shenr@wsaccess.com



作者 Re:Zeus实现XML-JAVA的数据绑定 [Re:ftang]
jeez



发贴: 0
积分: 0
于 2003-04-19 21:16 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
我觉得通过dtd实现binding比Castor通过mapping.xml来实现有点生硬。诸位以为呢?


作者 Re:Zeus实现XML-JAVA的数据绑定 [Re:palatum]
jeez



发贴: 0
积分: 0
于 2003-04-22 11:02 user profilesend a private message to usersearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
有关XML-JAVA的数据绑定的好文
ftp://www6.software.ibm.com/software/developer/library/x-databdopt.pdf




flat modethreaded modego to previous topicgo to next topicgo to back
  已读帖子
  新的帖子
  被删除的帖子
Jump to the top of page

   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923