key words: Digester? 解析xml
假設(shè)有下列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>
這是一份常用到的文件,現(xiàn)在我們需要將之映射到j(luò)ava 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等價
????????//?參數(shù)?0代表一個參數(shù),默認就是當(dāng)前讀的數(shù)據(jù)
????????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的屬性名稱完全對應(yīng),則直接提供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>
對應(yīng)的解析如下:
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().