key words: Digester 解析xml
假设有下列xml文件:
<?
xml version='1.0' encoding='utf-8'
?>
<
address-book
>
<
contact
myType
="individual"
>
<
name
>
Zane Pasolini
</
name
>
<
address
>
999 W. Prince St.
</
address
>
<
city
>
New York
</
city
>
<
province
>
NY
</
province
>
<
postalcode
>
10013
</
postalcode
>
<
country
>
USA
</
country
>
<
telephone
>
1-212-345-6789
</
telephone
>
</
contact
>
<
contact
myType
="business"
>
<
name
>
SAMOFIX d.o.o.
</
name
>
<
address
>
Ilica 47-2
</
address
>
<
city
>
Zagreb
</
city
>
<
province
></
province
>
<
postalcode
>
10000
</
postalcode
>
<
country
from
="cn"
>
Croatia
</
country
>
<
telephone
>
385-1-123-4567
</
telephone
>
</
contact
>
</
address-book
>
这是一份常用到的文件,现在我们需要将之映射到java bean,用Digester解析显得非常简单
public
class
AddressBookParser
{
/**
* Prints the contact information to standard output.
*
*
@param
contact the <code>Contact</code> to print out
*/
public
void
addContact(Contact contact)
{
System.out.println(
"
TYPE:
"
+
contact.getType());
System.out.println(
"
NAME:
"
+
contact.getName());
System.out.println(
"
ADDRESS:
"
+
contact.getAddress());
System.out.println(
"
CITY:
"
+
contact.getCity());
System.out.println(
"
PROVINCE:
"
+
contact.getProvince());
System.out.println(
"
POSTALCODE:
"
+
contact.getPostalcode());
System.out.println(
"
COUNTRY:
"
+
contact.getCountry());
System.out.println(
"
COUNTRY-From:
"
+
contact.getCountryFrom());
System.out.println(
"
TELEPHONE:
"
+
contact.getTelephone());
}
/**
* Configures Digester rules and actions, parses the XML file specified
* as the first argument.
*
*
@param
args command line arguments
*/
public
static
void
main(String[] args)
throws
IOException, SAXException
{
//
instantiate Digester and disable XML validation
Digester digester
=
new
Digester();
digester.setValidating(
false
);
//
instantiate AddressBookParser class
digester.addObjectCreate(
"
address-book
"
, AddressBookParser.
class
);
//
instantiate Contact class
digester.addObjectCreate(
"
address-book/contact
"
, Contact.
class
);
//
set type property of Contact instance when 'type' attribute is found
//
对有属性的值通过setProperties方法
digester.addSetProperties(
"
address-book/contact
"
,
"myType", "type"
);
//
set different properties of Contact instance using specified methods
//
addCallMethod与addBeanPropertySetter等价
//
参数 0代表一个参数,默认就是当前读的数据
digester.addCallMethod(
"
address-book/contact/name
"
,
"
setName
"
,
0
);
digester.addCallMethod(
"
address-book/contact/address
"
,
"
setAddress
"
,
0
);
digester.addCallMethod(
"
address-book/contact/address
"
,
"
setAddress
"
,
0
);
digester.addCallMethod(
"
address-book/contact/city
"
,
"
setCity
"
,
0
);
digester.addCallMethod(
"
address-book/contact/province
"
,
"
setProvince
"
,
0
);
digester.addCallMethod(
"
address-book/contact/postalcode
"
,
"
setPostalcode
"
,
0
);
digester.addCallMethod(
"
address-book/contact/country
"
,
"
setCountry
"
,
0
);
//
增加country的属性 : from
digester.addSetProperties(
"
address-book/contact/country
"
,
"from","countryFrom"
);
digester.addCallMethod(
"
address-book/contact/telephone
"
,
"
setTelephone
"
,
0
);
//
call 'addContact' method when the next 'address-book/contact' pattern is seen
digester.addSetNext(
"
address-book/contact
"
,
"
addContact
"
);
//
now that rules and actions are configured, start the parsing process
AddressBookParser abp
=
(AddressBookParser) digester.parse(
new
File(
"
c://addressbook.xml
"
));
}
/**
* JavaBean class that holds properties of each Contact entry.
* It is important that this class be public and static, in order for
* Digester to be able to instantiate it.
*/
public
static
class
Contact
{
private
String type;
private
String name;
private
String address;
private
String city;
private
String province;
private
String postalcode;
private
String country;
//
增加一个country的属性: from
private
String countryFrom;
private
String telephone;
public
void
setType(String newType)
{
type
=
newType;
}
public
String getType()
{
return
type;
}
public
void
setName(String newName)
{
name
=
newName;
}
public
String getName()
{
return
name;
}
public
void
setAddress(String newAddress)
{
address
=
newAddress;
}
public
String getAddress()
{
return
address;
}
public
void
setCity(String newCity)
{
city
=
newCity;
}
public
String getCity()
{
return
city;
}
public
void
setProvince(String newProvince)
{
province
=
newProvince;
}
public
String getProvince()
{
return
province;
}
public
void
setPostalcode(String newPostalcode)
{
postalcode
=
newPostalcode;
}
public
String getPostalcode()
{
return
postalcode;
}
public
void
setCountry(String newCountry)
{
country
=
newCountry;
}
public
String getCountry()
{
return
country;
}
public
void
setTelephone(String newTelephone)
{
telephone
=
newTelephone;
}
public
String getTelephone()
{
return
telephone;
}
public
String getCountryFrom() {
return
countryFrom;
}
public
void
setCountryFrom(String countryFrom) {
this
.countryFrom
=
countryFrom;
}
}
}
在 AjaxChat 中的读取房间信息的方式显得更简洁
房间的xml配置文件如下:
<
rooms
>
<
room
id
="1"
name
="General Topics"
/>
<
room
id
="2"
name
="Programming"
/>
<
room
id
="3"
name
="Movies"
/>
<
room
id
="4"
name
="Music"
/>
<
room
id
="5"
name
="Television"
/>
</
rooms
>
解析代码如下 :
public
synchronized
void
init(InputStream isConfigFile) {
log.debug(
"
init()
"
);
if
(isConfigFile
!=
null
) {
//
Read in rooms config and create beans, hand off to DAO.
Digester digester
=
new
Digester();
digester.setValidating(
false
);
digester.push(
this
);
digester.addObjectCreate(
"
rooms/room
"
,
"
org.apache.struts.apps.ajaxchat.dto.RoomDTO
"
);
//注意这里,如果xl的属性名称和bean的属性名称完全对应,则直接提供xml的位置即可
digester.addSetProperties(
"
rooms/room
"
);
digester.addSetNext(
"
rooms/room
"
,
"
addRoom
"
);
try
{
digester.parse(isConfigFile);
log.info(
"
***** Rooms =
"
+
rooms);
}
catch
(IOException ioe) {
ioe.printStackTrace();
}
catch
(SAXException se) {
se.printStackTrace();
}
}
}
//
End init().
如果在xml文件中增加非attribute则更改后的配置文件如下:
<
rooms
>
<
room
id
="1"
name
="General Topics"
/>
<
room
id
="2"
name
="Programming"
/>
<
room
id
="3"
name
="Movies"
/>
<
room
id
="4"
name
="Music"
/>
<
room
id
="5"
name
="Television"
/>
<
room
>
<
id
>
6
</
id
>
<
name
>
shit
</
name
>
</
room
>
<
room
>
<
id
>
7
</
id
>
<
name
>
haha
</
name
>
</
room
>
</
rooms
>
对应的解析如下:
public
synchronized
void
init(InputStream isConfigFile) {
log.debug(
"
init()
"
);
if
(isConfigFile
!=
null
) {
//
Read in rooms config and create beans, hand off to DAO.
Digester digester
=
new
Digester();
digester.setValidating(
false
);
digester.push(
this
);
digester.addObjectCreate(
"
rooms/room
"
,
"
org.apache.struts.apps.ajaxchat.dto.RoomDTO
"
);
digester.addSetProperties(
"
rooms/room
"
);
//增加addCallMethod方法
digester.addCallMethod(
"rooms/room/id","setId",0
);
digester.addCallMethod(
"rooms/room/name","setName",0
);
digester.addSetNext(
"
rooms/room
"
,
"
addRoom
"
);
try
{
digester.parse(isConfigFile);
log.info(
"
***** Rooms =
"
+
rooms);
}
catch
(IOException ioe) {
ioe.printStackTrace();
}
catch
(SAXException se) {
se.printStackTrace();
}
}
}
//
End init().