每日一得

不求多得,只求一得 about java,hibernate,spring,design,database,Ror,ruby,快速开发
最近关心的内容:SSH,seam,flex,敏捷,TDD
本站的官方站点是:颠覆软件

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  220 随笔 :: 9 文章 :: 421 评论 :: 0 Trackbacks
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().

posted on 2006-09-06 23:32 Alex 阅读(20864) 评论(19)  编辑  收藏 所属分类: java

评论

# re: 用Digester解析xml到bean 2006-09-07 16:01 山风小子
写的很好:-)  回复  更多评论
  

# re: 用Digester解析xml到bean 2006-09-08 22:10 巴哈姆特
不错,,值得参考!  回复  更多评论
  

# re: 用Digester解析xml到bean 2006-10-19 17:33 villagehead
不错。

另外,这两句:
digester.addCallMethod("rooms/room/id","setId",0);
digester.addCallMethod("rooms/room/name","setName",0);

还可以用
digester.addBeanPropertySetter("rooms/room/id");
digester.addBeanPropertySetter("rooms/room/name");

的形式

另外的另外,回字有4种写法。;)  回复  更多评论
  

# re: 用Digester解析xml到bean 2007-01-26 18:00 zhyiwww
看过,有收获。  回复  更多评论
  

# re: 用Digester解析xml到bean 2007-02-12 09:19 qq
不错,非常不错!  回复  更多评论
  

# re: 用Digester解析xml到bean 2007-02-12 10:05 qq
我自己实践了一下,觉得效果非常不错!省去了DOM操作的细节,但是缺点是操作文档不灵活。需要写很多代码。  回复  更多评论
  

# re: 用Digester解析xml到bean 2007-10-25 12:54 wdd
为什么按你一模一样的敲上!并且是运行是报此错呢?
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at org.apache.commons.digester.Digester.<init>(Digester.java:299)
at AddressBookParser.main(AddressBookParser.java:34)  回复  更多评论
  

# re: 用Digester解析xml到bean 2008-01-24 09:05 JAVA 小白
<persistence-unit name="aa">
<class>a1</class>
<class>a2</class>
<class>a3</class>
</persistence-unit>

<class>标签怎么实现

请指教。  回复  更多评论
  

# re: 用Digester解析xml到bean 2008-05-11 17:42 学海无涯
为什么javabean必须是静态的类?
请高手指点,谢谢了  回复  更多评论
  

# re: 用Digester解析xml到bean 2008-07-24 14:07 aga
javabean不必一定是静态类
to ../../../*
你没有加包
commons-digester\commons-logging\commons-beanutil似乎还有一个
  回复  更多评论
  

# re: 用Digester解析xml到bean[未登录] 2008-08-30 23:46 54powerman
手动写bean,够麻烦  回复  更多评论
  

# re: 用Digester解析xml到bean 2009-06-01 16:18 sheng
如果层次太深 还是让人很伤心的 它有没有提供 //province 这中形式呢

它是xpath的检索方式吗??

刚学习 多指教

谢谢  回复  更多评论
  

# re: 用Digester解析xml到bean 2009-07-02 16:45 ×××××
@wdd
少包没导入  回复  更多评论
  

# re: 用Digester解析xml到bean 2009-11-24 09:39 路过
当属性为int时,怎么调用addCallMethod方法?  回复  更多评论
  

# re: 用Digester解析xml到bean 2010-10-23 21:11 GANK
写的不错,值得学习!!  回复  更多评论
  

# re: 用Digester解析xml到bean 2014-04-16 14:03 ferrari
包导错了
这个目录下的import org.apache.commons.digester.Digester;  回复  更多评论
  

# re: 用Digester解析xml到bean 2014-07-01 14:17 fsgs
gdsfssdgdsg  回复  更多评论
  

# re: 用Digester解析xml到bean 2014-07-01 14:17 fsgs
不是太会
@  回复  更多评论
  

# re: 用Digester解析xml到bean[未登录] 2014-08-07 17:16 lee
哪四种@villagehead
  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问