优雅天平
享受喧嚣 安于平静
posts(18)
comments(167)
trackbacks(0)
BlogJava
联系
聚合
管理
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
给我留言
查看公开留言
查看私人留言
随笔档案
(18)
2006年4月 (1)
2006年3月 (1)
2005年12月 (3)
2005年10月 (2)
2005年9月 (1)
2005年7月 (2)
2005年6月 (3)
2005年3月 (2)
2005年2月 (3)
文章分类
(62)
eclipse(2)
Guitar(11)
J2EE相关(5)
JAVA基础(7)
Solaris相关(1)
WAP相关(1)
web services(12)
web页面基础(4)
开源相关(16)
数据库/仓库(2)
模式相关(1)
文章档案
(61)
2006年2月 (1)
2006年1月 (3)
2005年12月 (32)
2005年11月 (8)
2005年9月 (6)
2005年8月 (1)
2005年6月 (6)
2005年5月 (1)
2005年3月 (1)
2005年2月 (2)
相册
大事记
我的照片
blog
小江西
铁手剑谱的blog-strust
陶永胜书法艺术中心
站点搜藏
Matrix-与Java共舞
OpenSource
中国java开发网
搜索
积分与排名
积分 - 140782
排名 - 440
最新评论
1. re: JFreeChart完全攻略示例各种方法和属性[未登录]
sdfg
--111
2. re: JFreeChart完全攻略示例各种方法和属性
分数线烦不烦很舒服发个号发给合适的给他发所提供合适的土壤规范不能是纳税人他呢过生日能接受洒脱人呢是vae回复身体然后呢托管人粉红丝带让他反感 受托人复活币善待他人回事
--倒萨倒
3. re: Jcreator注册码[未登录]
有谁有jcreator 5.0 pro的注册码呀?跪求
--liu
4. re: 开启log4j的记录源代码行号的配置,会对系统性能产生影响!
怎么说呢?理解的有点片面。。。jdk1.4之前的话的确对性能影响比较大,自从1.4开始引入了StackTraceElement之后,对性能影响不是那么大。。。
--黄大仙
5. re: 请问MYECLIPSE在哪里输入注册码呀?[未登录]
对我这个初学者有帮助,嘿嘿。
--Flyer
阅读排行榜
1. Jcreator注册码(22600)
2. java日期相减问题(20213)
3. Myeclipse注册码(13917)
4. jbuilder 2006 破解文件(13653)
5. 修改 Oracle9i 8080端口问题(2862)
评论排行榜
1. jbuilder 2006 破解文件(58)
2. Jcreator注册码(50)
3. Myeclipse注册码(18)
4. JBuilder2005光标问题更好的解决方法(6)
5. B/S结构程序等待查询结果超时问题(5)
View Post
使用JAXB处理XML文档--先睹为快
转载于cnjsp.com
作者:
AYellow
[2002-04-06]
关键词:Java,XML,JAXB,DTD,绑定模式(Binding Schema),验证(validate),marshal,unmarshal
JAXB以其方便的XML数据处理能力可能会引起你的兴趣。你可能还不了解JAXB是什么,想要知道它到底有什么好处,如果这是你需要的,你才会再花时间去细细的研究它,或者你只需要使用最基本的功能。然而Sun关于JAXB的文档有80页之多。我想大部分人都没有耐心看完这样的长篇大论。本文以简短的篇幅介绍了JAXB的基本使用,算是先睹为快吧。本站提供
JAXB1.0 early access
版本的下载。欢迎与我讨论: mailto:boyofjava@sina.com
本文假设你会使用Java编程,了解并能够看懂XML,DTD。
1 为什么要使用JAXB
在Java中处理XML数据的常规方法有SAX,DOM等。其中SAX使用起来很麻烦,不能修改XML数据;而DOM的处理大文档速度非常的慢,易用性也不必SAX好到哪里去。实际上,无论是SAX还是DOM都不是专门为Java准备的,它们都是访问XML文档的统一底层接口,与语言无关。
现在我们有了另外的选择。这就是JAXB和JDOM。JDOM与本文无关,目前最新的版本是beta8,感兴趣的话,可以访问http://www.jdom.org/。
JAXB的全名是Java ™ Architecture for XML Binding,目前是1.0的early access版本,在Sun的Java站点只有注册为成员才能够下载。JAXB的特点就是将你用DTD定义好的XML文档映射为Java对象,提供简单、快速的数据操作方式。要访问XML中的元素、属性只要通过相应对象上的一系列getter和 setter方法。你还可以通过marshal方法将对象的数据写进XML文件,通过unmarshal方法将XML文件的数据读入对象,通过validate方法验证XML文件是否符合DTD的约束。JAXB的缺点就在于只能访问特定的(也就是你用DTD定义的)XML文档。
2 JAXB如何工作
JAXB包括了一个运行类库和一个模式编译器。首先你要定义XML的DTD,然后编写一个绑定模式(Binding Schema)。DTD定义了XML文档,绑定模式也是一个XML文件,指出DTD定义的XML文档如何被映射为Java对象。运行编译器,将DTD和绑定模式作为参数传给编译器,编译器就会生成Java代码。编译生成的Java代码,通过这些代码就可以访问XML文档了。
3 JAXB的安装
以1.0 early access为例,它不包含在JDK中,先到http://java.sun.com/xml下载。注意由于是早期版本,需要先登录才能下载,本文附带的源码包含了JAXB1.0 early access。下载后将文件解压缩,在lib目录中有两个文件。jaxb-rt-1.0-ea.jar是运行支持库,jaxb-xjc-1.0-ea.jar是模式编译器。注意bin目录中的xjc文件只能在UNIX下使用,如果你的系统是Windows,那么你需要在命令行窗口手工输入命令来编译。为了在任何地方都可以运行模式编译器和它生成的代码,我们要把这两的文件加入CLASSPATH。一个简单的办法是把这两个文件拷贝到jre/lib/ext下。
4 一个简单的例子
有这样一个XML文档。它描述书的列表,举例如下:
//exampleA.xml
<?xml version=
"1.0"
encoding=
"GBK"
?>
<bookList>
<book>
<name>Java编程入门</name>
<author>张三</author>
<publishDate>2002-6-6</publishDate>
<price>35.0</price>
</book>
<book>
<name>XML在Java中的应用</name>
<author>李四</author>
<publishDate>2002-9-16</publishDate>
<price>92.0</price>
</book>
</bookList>
其DTD文件如下:
//bookList.dtd
<!ELEMENT bookList (book)*>
<!ELEMENT book(name,author,publishDate,price)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT publishDate (#PCDATA)>
<!ELEMENT price (#PCDATA)>
现在我们就来编写一个最简单的绑定模式,其文件扩展名应该为xjs。
//bookList.xjs
<xml-java-binding-schema version=
"1.0-ea"
>
<element name=
"bookList"
type=
"class"
root=
"true"
/>
</xml-java-binding-schema>
现在就可以运行模式编译器生成Java代码,请先保证CLASSPATH中包含了JAXB的两个JAR文件。Windows用户注意bin目录下的那个文件是没用的。在命令行运行:
java com.sun.tools.xjc.Main bookList.dtd bookList.xjs
如果没出问题,编译器就生成了Book.java,BookList.java两个文件。你不用去理解这两个源文件里面的代码,只要知道怎么使用它们提供的方法就可以了。它们的继承结构都是这样的:
java.lang.
Object
javax.xml.bind.ValidatableObject
javax.xml.bind.MarshallableObject
javax.xml.bind.MarshallableRootElement
BookList or
Book
BookList.java主要包含了以下方法
BookList()
//构造函数
List
getBook()
//得到书的集合,List中的对象实际类型是Book,可以添加、修改、删除其中的元素
void
deleteBook()
//删除集合
void
emptyBook()
//删除并生成一个新的空集合
void
marshal(X)
//将数据写进XML文档
void
unmarshal(X)
//将数据从XML文档读入对象
void
validate(X)
//检查是否符合DTD约束,同时检查子树。在这个例子中就是BookList的Book集合
void
validateThis()
//检查是否符合DTD约束,不检查子树
其中marshal,unmarshal,validate被重载,有多种参数形式(可以参考JAXB的API文档)。
Book.java主要包含了以下方法
Book
()
String
getName()
String
getAuthor()
String
getPublishDate()
String
getPrice()
void
setName(
String
x)
void
setAuthor(
String
x)
void
setPublishDate(
String
x)
void
setPrice(
String
x)
void
marshal()
void
unmarshal()
void
validate()
现在我们就可以使用这两个文件访问XML了。首先编译这两个文件。编写一个Test.java文件,把它和生成的两个文件以及前面的exampleA.xml放在一起。这个程序从 exampleA.xml读入数据,作修改(把第一本书作者改成王五)后写入exampleB.xml。因为中文的编码问题,所以我们需要多一点手续。
//Test.java
import
java.io.*;
import
java.util.*;
import
javax.xml.bind.*;
import
javax.xml.marshal.*;
public
class
Test{
public
static
void
main(
String
[] args)
throws
Exception
{
BookList bl =
new
BookList();
FileInputStream
fis =
new
FileInputStream
(
"exampleA.xml"
);
try
{
bl = bl.unmarshal(fis);
}
finally
{
fis.close();
}
List
books = bl.getBook();
Book
b = (
Book
)books.get(0);
b.setAuthor(
"王五"
);
bl.validate();
//先验证,不然marshal会出错
FileOutputStream
fos =
new
FileOutputStream
(
"exampleB.xml"
);
XMLWriter xw =
new
XMLWriter(fos,
"GBK"
);
try
{
bl.marshal(xw);
}
finally
{
fos.close();
}
}
}
编译运行,生成的文件exampleB.xml如下:
<?xml version=
"1.0"
encoding=
"GBK"
?>
<bookList>
<book>
<name>Java编程入门</name>
<author>王五</author>
<publishDate>2002-6-6</publishDate>
<price>35.0</price></book>
<book>
<name>XML在Java中的应用</name>
<author>李四</author>
<publishDate>2002-9-16</publishDate>
<price>92.0</price></book></bookList>
5 更进一步:数据类型转换
你可能已经注意到在上面的例子中,生成的Book对象的getPrice方法返回的是String,实际上它应该是float。同样publishDate以该是日期类型,而不是字符串。这是因为我们的绑定模式写得太简单了,模式编译器生成了默认的String类型。现在我们这样写:
//bookList2.xjs
<xml-java-binding-schema version=
"1.0-ea"
>
<element name=
"bookList"
type=
"class"
root=
"true"
/>
<element name=
"price"
type=
"value"
convert=
"float"
/>
<element name=
"publishDate"
type=
"value"
convert=
"TransDate"
/>
<conversion name=
"TransDate"
type=
"java.util.Date"
parse=
"TransDate.parseDate"
print=
"TransDate.printDate"
/>
</xml-java-binding-schema>
用java com.sun.tools.xjc.Main bookList.dtd bookList2.xjs运行编译器。生成的Book文件的相应代码为:
float
getPrice()
java.util.
Date
getPublishDate()
bookList2.xjs第3行将Price转换成了float类型,float类型是一个简单类型,因此用convert="float"描述就可以了。而 publishDate需要转变成java.util.Date,这是一个类,而且他没有以字符串作为参数的构造函数。parse="TransDate.parseDate"就表示使用unmarshal读取数据的时候,会调用TransDate.parseDate()方法。这个静态方法以字符串为参数,返回java.util.date。print="TransDate.printDate"的作用相反。TransDate这个类需要我们提供。
//TransDate.java
import
java.util.
Date
;
public
class
TransDate {
private
static
java.text.
SimpleDateFormat
df
=
new
java.text.
SimpleDateFormat
(
"yyyy-MM-dd"
);
public
static
Date
parseDate(
String
d) {
try
{
return
df.parse(d);
}
catch
(java.text.
ParseException
pe) {
System
.out.print(pe);
return
new
Date
();
}
}
public
static
String
printDate(
Date
d) {
return
df.format(d);
}
}
6 那些使JAXB能够做到,但本文没有提到的
本文提供的这个例子很简单,实际上JAXB还可以定义文档的哪些元素(属性)可以被转换成类,哪些被转换成类的属性。处理元素的属性。处理枚举值。为一些元素共同的子元素生成接口(因为JAXB不支持NameSpace),定义继承结构等等。
7 JAXB不能做到的
Sun的文档里提到的:
仅支持用DTD定义XML
不支持NameSpace
不支持内部子集、NOTATIONs、ENTITY、ENTITIES等。
另外,我发现如果要写一条处理指令到XML文档中,例如指定转换的样式单
<?xml-stylesheet href=”a.xsl” type=”text/xsl”?>
在JAXB中好像做不到,在javax.xml.marshal.XMLWriter中有一个chars(String str)方法,可以把字符串到XML文件的声明后面,但是这个方法对特殊字符作了转义,也就是没办法可以做到。这很奇怪,因为这是一个常用的功能,要实现也不难。也许还有我没有发现的办法。倒是有一个doctype方法可以写DOCTYPE声明。
posted on 2006-01-10 16:46
Victor
阅读(831)
评论(0)
编辑
收藏
所属分类:
web services
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理
相关文章:
使用JAXB处理XML文档--先睹为快
JAXM开发Web服务的构架和模式(good2)
用JAXM开发Web服务(good)
用JAXM发送和接收SOAP消息
SOAP Header:扩展SOAP能力的途径
使用SOAP开发java web服务--Axis开发方案
基于JAX-RPC的快速Web服务开发方案
深入探索SOAP1.1--使用SAAJ1.2.1
实现安全的AXIS Web服务,第2部分(转)
实现安全的AXIS Web服务,第1部分(转)