利用
XMLBean
轻轻松松读写
XML
一、关于
XML
解析
XML
在
Java
应用程序里变得越来越重要
,
广泛应用于数据存储和
交换
.
比如我们常见的配置文件
,
都是以
XML
方式存储的
. XML
还应用
于
Java Message Service
和
Web Services
等技术作为数据交换
.
因此
,
正确读写
XML
文档是
XML
应用的基础
.
Java
提供了
SAX
和
DOM
两种方式用于解析
XML,
但即便如此
,
要读写一个
稍微复杂的
XML,
也不是一件容易的事
.
二、
XMLBean
简介
Hibernate
已经成为目前流行的面向
Java
环境的对象
/
关系数据库映射工具
.
在
Hibernate
等对象
/
关系数据库映射工具出现之前
,
对数据库的操作是
通过
JDBC
来实现的
,
对数据库的任何操作
,
开发人员都要自己写
SQL
语句
来实现
.
对象
/
关系数据库映射工具出现后
,
对数据库的操作转成对
JavaBean
的操作
,
极大方便了数据库开发
.
所以如果有一个类似的工具能够
实现将对
XML
的读写转成对
JavaBean
的操作
,
将会简化
XML
的读写
,
即使对
XML
不熟悉的开发人员也能方便地读写
XML.
这个工具就是
XMLBean.
三、准备
XMLBean
和
XML
文档
XMLBean
是
Apache
的一个开源项目
,
可以从
http://www.apache.org
下载
,
最新的版本是
2.0.
解压后目录如下
:
xmlbean2.0.0
+---bin
+---docs
+---lib
+---samples
+---schemas
另外还要准备一个
XML
文档
(customers.xml),
在本文的例子里
,
我们将对这个文档进行读写操作
.
文档源码如下
:
<?
xml
version="1.0" encoding="UTF-8"?>
<
Customers
>
<
customer
>
<
id
>
1
</
id
>
<
gender
>
female
</
gender
>
<
firstname
>
Jessica
</
firstname
>
<
lastname
>
Lim
</
lastname
>
<
phoneNumber
>
1234567
</
phoneNumber
>
<
address
>
<
primaryAddress
>
<
postalCode
>
350106
</
postalCode
>
<
addressLine1
>
#25-1
</
addressLine1
>
<
addressLine2
>
SHINSAYAMA 2-CHOME
</
addressLine2
>
</
primaryAddress
>
<
billingAddress
>
<
receiver
>
Ms Danielle
</
receiver
>
<
postalCode
>
350107
</
postalCode
>
<
addressLine1
>
#167
</
addressLine1
>
<
addressLine2
>
NORTH TOWER HARBOUR CITY
</
addressLine2
>
</
billingAddress
>
</
address
>
</
customer
>
<
customer
>
<
id
>
2
</
id
>
<
gender
>
male
</
gender
>
<
firstname
>
David
</
firstname
>
<
lastname
>
Bill
</
lastname
>
<
phoneNumber
>
808182
</
phoneNumber
>
<
address
>
<
primaryAddress
>
<
postalCode
>
319087
</
postalCode
>
<
addressLine1
>
1033 WS St.
</
addressLine1
>
<
addressLine2
>
Tima Road
</
addressLine2
>
</
primaryAddress
>
<
billingAddress
>
<
receiver
>
Mr William
</
receiver
>
<
postalCode
>
672993
</
postalCode
>
<
addressLine1
>
1033 WS St.
</
addressLine1
>
<
addressLine2
>
Tima Road
</
addressLine2
>
</
billingAddress
>
</
address
>
</
customer
>
</
Customers
>
这是一个客户的数据模型
,
每个客户都有客户编号
(ID),
姓名
,
性别
(gender),
电话号码
(phoneNumber)
和地址
,
其中地址有两个
:
首要地址
(PrimaryAddress)
和帐单地址
(BillingAddress),
每个地址有邮编
,
地址
1,
和地址
2
组成
.
其中帐单地址还有收件人
(receiver).
此外
,
还要准备一个配置文件
(
文件名
customer.xsdconfig),
这个文件的
作用我后面会讲
,
它的内容如下
:
<
xb:config
xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">
<
xb:namespace
>
<
xb:package
>
sample.xmlbean
</
xb:package
>
</
xb:namespace
>
</
xb:config
>
四、
XMLBean
使用步骤
和其他面向
Java
环境的对象
/
关系数据库映射工具的使用步骤一样
,
在正式使用
XMLBean
前
,
我们要作两个准备
.
1.
生成
XML Schema
文件
什么是
XML Schema
文件
?
正常情况下
,
每个
XML
文件都有一个
Schema
文件
, XML Schema
文件是一个
XML
的约束文件
,
它定义了
XML
文件的结构和元素
.
以及对元素和结构的约束
.
通俗地讲
,
如果说
XML
文件是数据库里的记录
,
那么
Schema
就是表结构定义
.
为什么需要这个文件
? XMLBean
需要通过这个文件知道一个
XML
文件的
结构以及约束
,
比如数据类型等
.
利用这个
Schema
文件
,XMLBean
将会产生一系列相关的
Java Classes
来实现对
XML
的操作
.
而作为开发人员
,
则是利用
XMLBean
产生的
Java Classes
来完成对
XML
的操作而不需要
SAX
或
DOM.
怎样产生这个
Schema
文件呢
?
如果对于熟悉
XML
的开发人员
,
可以自己来写这个
Schema
文件
,
对于不熟悉
XML
的开发人员
,
可以通过一些工具来完成
.
比较有名的如
XMLSPY
和
Stylus Studio
都可以通过
XML
文件来生成
Schema
文件
.
加入我们已经生成这个
Schema
文件
(customer.xsd):
<?
xml
version="1.0" encoding="UTF-8"?>
<
xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<
xs:element
name="Customers">
<
xs:complexType
>
<
xs:sequence
>
<
xs:element
maxOccurs="unbounded" name="customer" type="customerType" />
</
xs:sequence
>
</
xs:complexType
>
</
xs:element
>
<
xs:complexType
name="customerType">
<
xs:sequence
>
<
xs:element
name="id" type="xs:int" />
<
xs:element
name="gender" type="xs:string" />
<
xs:element
name="firstname" type="xs:string" />
<
xs:element
name="lastname" type="xs:string" />
<
xs:element
name="phoneNumber" type="xs:string" />
<
xs:element
name="address" type="addressType" />
</
xs:sequence
>
</
xs:complexType
>
<
xs:complexType
name="addressType">
<
xs:sequence
>
<
xs:element
name="primaryAddress" type="primaryAddressType" />
<
xs:element
name="billingAddress" type="billingAddressType" />
</
xs:sequence
>
</
xs:complexType
>
<
xs:complexType
name="primaryAddressType">
<
xs:sequence
>
<
xs:element
name="postalCode" type="xs:string" />
<
xs:element
name="addressLine1" type="xs:string" />
<
xs:element
name="addressLine2" type="xs:string" />
</
xs:sequence
>
</
xs:complexType
>
<
xs:complexType
name="billingAddressType">
<
xs:sequence
>
<
xs:element
name="receiver" type="xs:string" />
<
xs:element
name="postalCode" type="xs:string" />
<
xs:element
name="addressLine1" type="xs:string" />
<
xs:element
name="addressLine2" type="xs:string" />
</
xs:sequence
>
</
xs:complexType
>
</
xs:schema
>
2.
利用
scomp
来生成
Java Classes
scomp
是
XMLBean
提供的一个编译工具
,
它在
bin
的目录下
.
通过这个工具
,
我们可以将以上的
Schema
文件生成
Java Classes.
scomp
的语法如下
:-
scomp [options] [dirs]* [schemaFile.xsd]* [service.wsdl]* [config.xsdconfig]*
主要参数说明
:
-src [dir] --
生成的
Java Classes
存放目录
-srconly --
不编译
Java Classes,
不产生
Jar
文件
-out [jarFileName] --
生成的
Jar
文件
,
缺省是
xmltypes.jar
-compiler -- Java
编译器的路径
,
即
Javac
的位置
schemaFile.xsd -- XML Schema
文件位置
config.xsdconfig -- xsdconfig
文件的位置
,
这个文件主要用来制定生成的
Java Class
的一些文件名规则和
Package
的名称
,
在本文
,package
是
sample.xmlbean
在本文
,
我是这样运行的
:
scomp -src buildsrc -out buildcustomerXmlBean.jar schemacustomer.xsd -compiler C:jdk142_04injavac customer.xsdconfig
这个命令行的意思是告诉
scomp
生成
customerXmlBean.jar,
放在
build
目录下
,
同时生成源代码放在
buildsrc
下
, Schema
文件是
customer.xsd,xsdconfig
文件是
customer.xsdconfig.
其实
,
生成的
Java
源代码没有多大作用
,
我们要的是
jar
文件
.
我们先看一下
buildsrcsamplexmlbean
下生成的
Classes.
CustomersDocument.java --
整个
XML
文档的
Java Class
映射
CustomerType.java --
节点
sustomer
的映射
AddressType.java --
节点
address
的映射
BillingAddressType.java --
节点
billingAddress
的映射
PrimaryAddressType.java --
节点
primaryAddress
的映射
好了
,
到此我们所有的准备工作已经完成了
.
下面就开始进入重点:利用刚才生成的
jar
文件读写
XML.
五、利用
XMLBean
读
XML
文件
新建一个
Java Project,
将
XMLBean2.0.0lib
下的
Jar
文件和刚才我们生成的
customerXmlBean.jar
加入到
Project
的
ClassPath.
新建一个
Java Class: CustomerXMLBean.
源码如下
:
package
com.sample.reader;
import
java.io.File;
import
sample.xmlbean.*;
import
org.apache.commons.beanutils.BeanUtils;
import
org.apache.xmlbeans.XmlOptions;
public
class
CustomerXMLBean {
private
String
filename
=
null
;
public
CustomerXMLBean(String filename) {
super
();
this
.
filename
= filename;
}
public
void
customerReader() {
try
{
File xmlFile =
new
File(
filename
);
CustomersDocument doc = CustomersDocument.Factory.parse(xmlFile);
CustomerType[] customers = doc.getCustomers().getCustomerArray();
for
(
int
i = 0; i < customers.length; i++) {
CustomerType customer = customers[i];
println(
"Customer#"
+ i);
println(
"Customer ID:"
+ customer.getId());
println(
"First name:"
+ customer.getFirstname());
println(
"Last name:"
+ customer.getLastname());
println(
"Gender:"
+ customer.getGender());
println(
"PhoneNumber:"
+ customer.getPhoneNumber());
// Primary address
PrimaryAddressType primaryAddress = customer.getAddress().getPrimaryAddress();
println(
"PrimaryAddress:"
);
println(
"PostalCode:"
+ primaryAddress.getPostalCode());
println(
"AddressLine1:"
+ primaryAddress.getAddressLine1());
println(
"AddressLine2:"
+ primaryAddress.getAddressLine2());
// Billing address
BillingAddressType billingAddress = customer.getAddress().getBillingAddress();
println(
"BillingAddress:"
);
println(
"Receiver:"
+ billingAddress.getReceiver());
println(
"PostalCode:"
+ billingAddress.getPostalCode());
println(
"AddressLine1:"
+ billingAddress.getAddressLine1());
println(
"AddressLine2:"
+ billingAddress.getAddressLine2());
}
}
catch
(Exception ex) {
ex.printStackTrace();
}
}
private
void
println(String str) {
System.
out
.println(str);
}
public
static
void
main(String[] args) {
String filename =
"F://JavaTest//Eclipse//XMLBean//xml//customers.xml"
;
CustomerXMLBean customerXMLBean =
new
CustomerXMLBean(filename);
customerXMLBean.customerReader();
}
}
运行它
,
参看输出结果
:
Customer#0
Customer ID:1
First name:Jessica
Last name:Lim
Gender:female
PhoneNumber:1234567
PrimaryAddress:
PostalCode:350106
AddressLine1:#25-1
AddressLine2:SHINSAYAMA 2-CHOME
BillingAddress:
Receiver:Ms Danielle
PostalCode:350107
AddressLine1:#167
AddressLine2:NORTH TOWER HARBOUR CITY
Customer#1
Customer ID:2
First name:David
Last name:Bill
Gender:male
PhoneNumber:808182
PrimaryAddress:
PostalCode:319087
AddressLine1:1033 WS St.
AddressLine2:Tima Road
BillingAddress:
Receiver:Mr William
PostalCode:672993
AddressLine1:1033 WS St.
AddressLine2:Tima Road
怎么样
,
是不是很轻松
? XMLBean
的威力
.
六、利用
XMLBean
写
XML
文件
利用
XMLBean
创建一个
XML
文档也是一件轻而易举的事
.
我们再增加一个
Method,
请看一下的
Java Class:
public
void
createCustomer() {
try
{
// Create Document
CustomersDocument doc = CustomersDocument.Factory.newInstance();
// Add new customer
CustomerType customer = doc.addNewCustomers().addNewCustomer();
// set customer info
customer.setId(3);
customer.setFirstname(
"Jessica"
);
customer.setLastname(
"Lim"
);
customer.setGender(
"female"
);
customer.setPhoneNumber(
"1234567"
);
// Add new address
AddressType address = customer.addNewAddress();
// Add new PrimaryAddress
PrimaryAddressType primaryAddress = address.addNewPrimaryAddress();
primaryAddress.setPostalCode(
"350106"
);
primaryAddress.setAddressLine1(
"#25-1"
);
primaryAddress.setAddressLine2(
"SHINSAYAMA 2-CHOME"
);
// Add new BillingAddress
BillingAddressType billingAddress = address.addNewBillingAddress();
billingAddress.setReceiver(
"Ms Danielle"
);
billingAddress.setPostalCode(
"350107"
);
billingAddress.setAddressLine1(
"#167"
);
billingAddress.setAddressLine2(
"NORTH TOWER HARBOUR CITY"
);
File xmlFile =
new
File(filename);
doc.save(xmlFile);
}
catch
(Exception ex) {
ex.printStackTrace();
}
}
修改
main method.
public
static
void
main(String[] args) {
String filename =
"F://JavaTest//Eclipse//XMLBean//xml//customers_new.xml"
;
CustomerXMLBean customerXMLBean =
new
CustomerXMLBean(filename);
customerXMLBean.createCustomer();
}
运行
,
打开
customers_new.xml:
<?
xml
version="1.0" encoding="UTF-8"?>
<
Customers
>
<
customer
>
<
id
>
3
</
id
>
<
gender
>
female
</
gender
>
<
firstname
>
Jessica
</
firstname
>
<
lastname
>
Lim
</
lastname
>
<
phoneNumber
>
1234567
</
phoneNumber
>
<
address
>
<
primaryAddress
>
<
postalCode
>
350106
</
postalCode
>
<
addressLine1
>
#25-1
</
addressLine1
>
<
addressLine2
>
SHINSAYAMA 2-CHOME
</
addressLine2
>
</
primaryAddress
>
<
billingAddress
>
<
receiver
>
Ms Danielle
</
receiver
>
<
postalCode
>
350107
</
postalCode
>
<
addressLine1
>
#167
</
addressLine1
>
<
addressLine2
>
NORTH TOWER HARBOUR CITY
</
addressLine2
>
</
billingAddress
>
</
address
>
</
customer
>
</
Customers
>
七、利用
XMLBean
修改
XML
文件
我们再增加一个
Method:
public
void
updateCustomer(
int
id,String lastname) {
try
{
File xmlFile =
new
File(filename);
CustomersDocument doc = CustomersDocument.Factory.parse(xmlFile);
CustomerType[] customers = doc.getCustomers().getCustomerArray();
for
(
int
i = 0; i < customers.length; i++) {
CustomerType customer = customers[i];
if
(customer.getId()==id){
customer.setLastname(lastname);
break
;
}
}
doc.save(xmlFile);
}
catch
(Exception ex) {
ex.printStackTrace();
}
}
main method:
public
static
void
main(String[] args) {
String filename =
"F://JavaTest//Eclipse//XMLBean//xml//customers_new.xml"
;
CustomerXMLBean customerXMLBean =
new
CustomerXMLBean(filename);
customerXMLBean.updateCustomer(3,
"last"
);
}
运行之后
,
我们将会看到客户编号为
3
的客户的
lastname
已经改为
last.
八、利用
XMLBean
删除一个
customer
再增加一个
Method:
public
void
deleteCustomer(
int
id){
try
{
File xmlFile =
new
File(filename);
CustomersDocument doc = CustomersDocument.Factory.parse(xmlFile);
CustomerType[] customers = doc.getCustomers().getCustomerArray();
for
(
int
i = 0; i < customers.length; i++){
CustomerType customer = customers[i];
if
(customer.getId()==id){
customer.setNil() ;
break
;
}
}
doc.save(xmlFile);
}
catch
(Exception ex){
ex.printStackTrace();
}
}
main method:
public
static
void
main(String[] args){
String filename =
"F://JavaTest//Eclipse//XMLBean//xml//customers_new.xml"
;
CustomerXMLBean customerXMLBean =
new
CustomerXMLBean(filename);
customerXMLBean.deleteCustomer(3);
}
运行
,
我们将会看到客户编号为
3
的客户的资料已经被删除
.
九、查询
XML
除了本文在以上讲述的
,
利用
XMLBean
能轻轻松松完成
XML
的读写操作外
,
结合
XPath
和
XQuery,
XMLBean
还能完成象
SQL
查询数据库一样方便地查询
XML
数据
.
关于
XML
查询以及如何创建
XML
数据库
,
我将在另一篇文章里讨论
.
十、结束语
XMLBean
能帮助我们轻易读写
XML,
这将有助于我们降低
XML
的学习和使用
,
有了这个基础
,
开发人员将为学习更多地
XML
相关技术和
Web Services,JMS
等其他
J2EE
技术打下良好地基础
.