XML
已经成为了我们开发过程中不可缺少的技术。我们可以用它来描述程序的配置,适配不同的数据格式,甚至作为
数据库
使用。
帮助处理
XML
的工具很多,它们让我们活得更轻松。
JakartaCommons
下的
Digester
就是一个不错的工具。它提供了一种将
XML
与
Java
对象进行映射的方便方法。这么说可能让新手更迷惑,还是举个例子吧!
我们有这样一个
XML
文件:
1.
2.
<!--Memos_2004-01-16.xml-->
3.
<?xmlversion=
"1.0"
?>
4.
<memos>
5.
<memo>
6.
<title>AboutJakatarcommonsDigester</title>
7.
<date>2004-01-1602:05</date>
8.
<body>WeareworkingonDigester1.6-dev.Becauseitsupportedread
9.
attributesofelement.Weshouldpayattentiontothereleasingof
10.
Digester
for
itschanging.</body>
11.
</memo>
12.
13.
<memo>
14.
<title>Ahha!It'sgoodnight!</title>
15.
<date>2004-01-164:19</date>
16.
<body>Ihasenhancedthebasicframeworkofmyappwithimproved
17.
architectureandperformance.It'stimetosleep.Goodnight,
18.
boys.</body>
19.
</memo>
20.
</memos>
这是我的备忘录,我用
xml
作为
“
数据库
”
。现在我们想用
Java
程序来读
/
写这个
“
数据库
”
应该怎么做呢?啊!对了,
SAX
、
DOM……
,好了,忘了它们吧!我们有更
Easy
的办法!
我们先来创建一个
Memo
类,它用来保存一条
Memo
。它有三个属性用来保存标题、日期以及
Memo
的正文。我们提供了公共的
Setter
和
Getter
,并且我们重载了
toString()
方法以便查看运行结果
1.
2.
/*Memo.java*/
3.
package
kitta.memo;
4.
1.
public
class
Memo
2.
{
3.
/*-----/InstanceField(s)/------------------------------------------------*/
4.
private
String_title;
5.
private
String_body;
6.
private
String_date;
7.
/*-----/Constructor(s)/---------------------------------------------------*/
8.
public
Memo()
9.
{
10.
/*donothingnow*/
11.
}
12.
13.
/*-----/Getter(s)&Setter(s)/--------------------------------------------*/
14.
public
StringgetBody()
15.
{
16.
return
_body;
17.
}
18.
19.
public
void
setBody(Stringbody)
20.
{
21.
_body=body;
22.
}
23.
24.
public
StringgetTitle()
25.
{
26.
return
_title;
27.
}
28.
29.
public
void
setTitle(Stringtitle)
30.
{
31.
_title=title;
32.
}
33.
34.
public
StringgetDate()
35.
{
36.
return
_date;
37.
}
38.
public
void
setDate(Stringdate)
39.
{
40.
_date=date;
41.
}
42.
/*-----/OverridedMethod(s)/----------------------------------------------*/
43.
public
StringtoString()
44.
{
45.
StringBufferbuf=
new
StringBuffer();
46.
buf.append(
"/t"
).append(_title);
47.
buf.append(
"/tat/t"
).append(_date).append(
"/n/n"
);
48.
buf.append(
"/t"
).append(_body).append(
"/n"
);
49.
buf.append(
"-----------------------------------------------------------/n"
);
50.
return
buf.toString();
51.
}
52.
}
然后是
Memos
类,它实际上是一个
Memo
对象的集合,完全可以用一个
Collection
的子类去代替它,但是这里之所以还是使用它主要是为了概念上的清晰。它同样很简单,一个私有属性
_memos
用来保存所有
Memo
对象的实例,一个共有方法
addMemo()
用来添加
Memo
,
toString()
方法的目的同上。
1.
/*Memos.java*/
2.
package
kitta.memo;
3.
4.
import
java.util.Collection;
5.
import
java.util.Iterator;
6.
import
java.util.Vector;
7.
8.
9.
public
class
Memos
10.
{
11.
/*-----/InstanceFields/--------------------------------------------------*/
12.
private
Collection_memos=
new
Vector();
13.
/*-----/Constructor(s)/---------------------------------------------------*/
14.
public
Memos()
15.
{
16.
/*donothing*/
17.
}
18.
/*-----/Getter(s)&Setter(s)/--------------------------------------------*/
19.
public
void
addMemo(Memomemo)
20.
{
21.
_memos.add(memo);
22.
}
23.
/*-----/OverridedMethod(s)/----------------------------------------------*/
24.
public
StringtoString()
25.
{
26.
StringBufferbuf=
new
StringBuffer();
27.
buf.append(
"-----------------------------------------------------------/n"
);
28.
buf.append(
"MemoApplication/n"
);
29.
buf.append(
"("
).append(_memos.size()).append(
"memostotalfound.)/n"
);
30.
buf.append(
"-----------------------------------------------------------/n"
);
31.
32.
for
(Iteratoritr=_memos.iterator();itr.hasNext();)
33.
{
34.
Memom=(Memo)itr.next();
35.
buf.append(m.toString());
36.
}
37.
return
buf.toString();
38.
}
39.
}
请注意
init
方法,它告诉
Digester
如何将
XML
中的数据映射到我们的
Java
对象。
1.
2.
package
kitta.memo;
3.
4.
import
java.io.IOException;
5.
import
java.io.InputStream;
6.
7.
import
org.apache.commons.digester.Digester;
8.
9.
public
class
MemoApp
10.
{
11.
/*-----/InstanceField(s)/------------------------------------------------*/
12.
private
Memos_memos;
13.
/*-----/Constructor(s)/---------------------------------------------------*/
14.
public
MemoApp()
15.
{
16.
/*donothing*/
17.
}
18.
/*-----/PrivateMethods(s)/-----------------------------------------------*/
19.
/**
20.
*InitializestheinstanceofDigester.
21.
*/
22.
private
void
init(Digesterdgstr)
23.
{
24.
/*
当遇到
memos
元素时创建一个
Memos
对象
*/
25.
dgstr.addObjectCreate(
"memos"
,Memos.
class
);
26.
/*
当遇到
memo
元素时创建一个
Memo
对象
*/
27.
dgstr.addObjectCreate(
"memos/memo"
,Memo.
class
);
28.
/*
当遇到
memos/memo/title
元素时,调用当前
Memo
对象的
setTitle
方法
*/
29.
dgstr.addBeanPropertySetter(
"memos/memo/title"
,
"title"
);
30.
/*
当遇到
memos/memo/body
元素时,调用当前
Memo
对象的
setBody*/
31.
dgstr.addBeanPropertySetter(
"memos/memo/body"
,
"body"
);
32.
/*
当遇到
memos/memo/date
元素时,调用当前
Memo
对象的
setDate
方法
*/
33.
dgstr.addBeanPropertySetter(
"memos/memo/date"
,
"date"
);
34.
/*
调用当前的
Memos
对象的
addMemo
方法,参数为当前的
Memo
对象
*/
35.
dgstr.addSetNext(
"memos/memo"
,
"addMemo"
);
36.
37.
}
38.
/**
39.
*printsdetailsofmemostostandardout.
40.
*/
41.
private
void
print()
42.
{
43.
System.out.println(_memos);
44.
}
45.
/**
46.
*mapsthexmldatatojavaobject
47.
*/
48.
private
void
load(InputStreamin)
throws
Exception
49.
{
50.
Digesterdgstr=
new
Digester();
- init(dgstr);
52.
try
53.
{
54.
_memos=(Memos)dgstr.parse(in);
55.
}
catch
(IOExceptione)
56.
{
57.
throw
new
Exception(
"ErroroccuredWhenloadingdata"
,e);
58.
}
59.
}
60.
/*-----/MainMethod/------------------------------------------------------*/
61.
public
static
void
main(String[]args)
throws
Exception
62.
{
63.
MemoAppmapp=
new
MemoApp();
64.
/*loadxmlfilefromclasspath*/
65.
mapp.load(MemoApp.
class
.getResourceAsStream(
"/kitta/memo/memo.xml"
));
66.
mapp.print();
67.
}
68.
}
Digester
用
"elem/elem/elem"
的方式来匹配
xml
中的元素。这非常直观,实际上我们很早就开始使用类似的方式了。
Digester
将其称为
Pattern
。
Digester
中还有一个重要的概念就是
Rule
。我们在
init
方法中所做的就是将
Pattern
和
Rule
关联起来。当
Digester
发现与我们所注册的
Pattern
匹配的
xml
元素时,就会调用我们注册时指定
Rule
来处理这个元素。
环境
以上代码的测试环境为
WindowsXP
、
JDK1.4.203
、
Digester1.5Release
。
相关资源
Degister
官方资源
Website:http://jakarta.apache.org/commons/digester/index.html
CVSconnection:scm:cvs:pserver:[email protected]:/home/cvspublic:jakarta-commons/digester/
CVSWebView:http://cvs.apache.org/viewcvs/jakarta-commons/digester/
一些其它地方的文章:
http://www-106.ibm.com/developerworks/java/library/j-lucene/
http://www.javaworld.com/javaworld/jw-10-2002/jw-1025-opensourceprofile.html
http://www.onjava.com/pub/a/onjava/2002/10/23/digester.html
最后
好啦!就这么简单!因为这只是一些基本的应用,它可以帮助你了解
Digester
,毕竟这只是一个
GettingStart
吗!要更好的应用,就要更深入的研究。