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 >
< 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;
}
}
}
{
/**
* 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 >
< 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().
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 >
< 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().
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().