`
uule
  • 浏览: 6305617 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

Digester解析XML文件

阅读更多

TOMCAT底层解析server.xml使用。

 

Dom4j是把一个xml文件全部读取到内存中,构建成一个DOM树来解析,所以Dom4j适合读取比较小的xml文件。

SAX是基于文件流来解析xml文件的,在读取xml文件流时,SAX会通过节点来触发相应的操作,也可以说SAX是基于文件流的事情触发机制来解析xml文件的。

Digeter是apache的common项目,作用是将XML转化成对象,使用者直接从对象中获取xml的节点信息。Digester是对SAX的包装,它也是基于文件流来解析xml文件,只不过这些解析操作对用户是透明的。Tomcat的配置文件conf/server.xml就是用Digester来读取的。

 

    一般用来读取xml文件的工具包有DOM、SAX和JDOM等,但用过的人都知道,它们属于比较底层的API,写起来代码量很大,而且如果修改了xml文件的格式,代码也要做大幅度的改动。而使用Apache Jakarta的Digester,解析XML文件非常方便且不需要过多的关心底层的具体解析过程。Digester本来仅仅是Jakarta Struts中的一个工具,用于处理struts-config.xml配置文件。显然,将XML文件转换成相应的Java对象是一项很通用的功能,这个工具理应具有更广泛的用途,所以很快它就在Jakarta Commons项目(用于提供可重用的Java组件库)中有了一席之地。Digester由"事件"驱动,通过调用预定义的规则操作对象栈,将XML文件转换为Java对象。

 

    工作原理如下:

              Digester底层采用SAX(Simple API for XML)析XML文件,所以很自然的,对象转换由"事件"驱动,在遍历每个节点时,检查是否有匹配模式,如果有,则执行规则定义的操作,比如创建特定的Java对象,或调用特定对象的方法等。此处的XML元素根据匹配模式(matching pattern)识别,而相关操作由规则(rule)定义。

 

    如下xml代码,右边是左边元素对应的匹配模式:

<datasources>          'datasources' 
  <datasource>         'datasources/datasource' 
    <name/>            'datasources/datasource/name' 
    <driver/>          'datasources/datasource/driver'  
  </datasource> 
  <datasource>         'datasources/datasource' 
    <name/>            'datasources/datasource/name' 
    <driver/>          'datasources/datasource/driver'  
  </datasource> 
</datasources> 

 

Tomcat与Digester的关系(注意该博客,很多资源)

Tomcat源码的catalina中利用Digester解析conf/server.xml

三个常见Digester例子

深入剖析Tomcat-Digester

理解Tomcat(一) 利用Digester解析xml文件

Digester处理多层的XML(仔细分析)

 

使用Digester解析XML配置文件

解析XML常用技术

 

 ==============================================================================

<?xml version="1.0" encoding="UTF-8?>  
<database>  
    <user userName="guest" password="guest">  
    </user>  
</database>  

 1.addObjectCreate(String rule,Class class)

设置节点与Java对象的映射规则,rule指定节点的筛选规则,class设置映射对象。SAX解析时,遇到rule指定的节节点,会创建一个class实例放入堆栈中。

比如:digester.addObectCreate("database/user","com.model.UserBean").解析遇到user节点时,会创建一个UserBean实例并放入堆栈中。

 

2.addSetProperties(String rule)

设置节点的属性设置规则。当解析遇到符合rule的节点时,根据属性列表中的属性值对,使用Java反射机制使用标准的JavaBean方法设置栈顶对象实例;

比如:digester.addSetProperties("database/user"),解析遇到user节点时,会获取键值对 userName=guest,password=guest,获得栈顶的UserBean对象,设置实例的userName、password属性;

解析元素上的属性 

 

3.addBeanPropertySetter(String rule)

该方法的作用及使用方法类似于addSetProperties,只不过它是用rule所指定的标签来调用对象的setter。

该方法在tomcat6中貌似没有。 

tomcat6中Digester类路径为:import org.apache.tomcat.util.digester.Digester;

不为:import org.apache.commons.digester.Digester;

 

4.addSetNext(String rule,String methodName)

设置当前rule节点与父节点的调用规则,当遇到rule节点时,调用堆栈中的次栈顶元素调用methodName方法。将栈顶元素作为次顶元素指定方法的输入参数。

比如:digester.addSetNext("database/user","addUser"),调用database实例的addUser,user为参数

 

5.addCallMethod(String rule,String methodName,int paraNumber)

该方法同样设置对象的属性,但更加灵活,不需要对象具有setter

根据rule规则指定的属性,调用对象的methodName方法,paraNumber参数是表示方法需要的参数个数,当paraNumber=0时,可以单独使用,不然需要配合addCallParam方法

比如:digester.addCallMethod("database/user/uerName","setUserName",0);

 

6.addCallParam(String rule,int paraIndex,String attributeName)

该方法与addCallMethod配合使用,根据rule指定的标签属性来调用方法

paraIndex表明需要填充的方法形参序号,从0开始,方法由addCallMethdo指定,attributeName指定标签属性名;

 

使用注意事项:

   1.Digester类调用的顺序,必须与XML数据文件绝对一致;

   2.Digester类依赖于JavaBean规范,类必须符合规范;

   3.XML文件中标签/属性的名称必须与Bean中的一致(包括大小写);

 

 ==================================================================

 关键方法说明

(1)    serverDigester.addObjectCreate("Server","com.test.server.digester.Server")

当解析xml文件时,遇到“Server”就初始化一个“com.test.server.digester.Server”对象,并且把该对象压入栈顶

(2)    serverDigester.addSetProperties("Server", "port", "port")

给Server对象注册port属性,当解析到Server节点的port属性时调用Server的setPort方法

(3)    serverDigester.addSetNext("Server/Listener", "addListener","com.test.server.digester.Listener")

当解析Server节点下的Listener节点的时候,调用Server对象的addListener方法,把当前Listener对象写入到Server对象中。无论Server节点下有多少个Listener节点,都会调用addListener方法

(4)    serverDigester.addCallMethod("Server/Service/Engine", "setEngine", 0)

Service中添加Engine,调用当前top object的setEngine函数,参数个数为0

addCallMethod与addBeanPropertySetter方法等价

 

Example1:

<?xml version="1.0" encoding="ISO-8859-1"?>
<student name="llin" age="16" grade="3">
    <subject name="math" teacher="yu" />
</student>

 

package digester;

import java.util.ArrayList;

public class Student {
    private String name;
    private int age;
    private int grade;
    private ArrayList<Subject> list = new ArrayList();
    
    public Student (){
        System.out.println("A student go to school");
    }

    public void add ( Subject subjects ){
        System.out.println("add Subjects " + subjects.getName() + " to the Student: "+ this.getName());
        list.add( subjects );
    }      
    /////////////////////////////////////////////////
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println( " set age of Student:" + name);
        this.age = age;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        System.out.println( " set score of Student:" + name );
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println(" set name pf Student" );
        this.name = name;
    }

    public ArrayList<Subject> getList (){
        return this.list;
    }
}

 

package digester;

public class Subject {
    private String name;
    private String teacher;

    public Subject() {
        System.out.println("One subjects waiting scheduling!");
    }

    public void print() {
        System.out.println("Subjects  :" + name + "of " + teacher + "in schedule");
    }    
    /////////////////////////////////////////////////////    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println(" set name of Subjects:" + name);
        this.name = name;
    }

    public String getTeacher() {
        return teacher;
    }

    public void setTeacher(String teacher) {
        System.out.println(" set teacher of Subjects :" + teacher);
        this.teacher = teacher;
    }   
}

 

 

package digester;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import org.apache.tomcat.util.digester.Digester;
import org.xml.sax.SAXException;

public class StudentDigesterTest {
	public static void main ( String [] args ) throws IOException{
		unUseRule();
		//useRule();
    }	
	
	public static void unUseRule(){
		File xml = new File( "../apache-tomcat-6.0.41-src/test/student.xml");
        Digester digester = new Digester();
        
        digester.addObjectCreate( "student" , "digester.Student" );
        digester.addSetProperties("student");
        digester.addObjectCreate("student/subject" , "digester.Subject");
        digester.addSetProperties("student/subject");
        //上面该句可用这句代替digester.addSetProperties("student/subject","subject","subject");
/**
* public void addSetProperties(String pattern,String attributeName,String propertyName)
*/
        digester.addSetNext("student/subject" , "add" );
        
        Student student = null;
        try {
            student = (Student)digester.parse(xml);
        }catch ( SAXException e ){
            System.out.println("parse with mistakes!");
        } catch (IOException e) {
			e.printStackTrace();
		}
        Iterator it = student.getList().iterator();
        while ( it.hasNext()) {

        }
	}
	
	public static void useRule(){
		File xml = new File( "../apache-tomcat-6.0.41-src/test/student.xml");
        Digester digester = new Digester();
        digester.addRuleSet(new MyRuleSet());
        
        Student student = null;
        try {
            student = (Student)digester.parse(xml);
        }catch ( SAXException e ){
            System.out.println("parse with mistakes!");
        } catch (IOException e) {
			e.printStackTrace();
		}
        Iterator it = student.getList().iterator();
        while ( it.hasNext()) {

        }
	}
}

  

package digester;

import org.apache.tomcat.util.digester.Digester;
import org.apache.tomcat.util.digester.RuleSetBase;

public class MyRuleSet  extends RuleSetBase{
    @Override
    public void addRuleInstances(Digester digester) {
    	digester.addObjectCreate( "student" , "digester.Student" );
        digester.addSetProperties("student");
        digester.addObjectCreate("student/subject" , "digester.Subject");
        digester.addSetProperties("student/subject");
        digester.addSetNext("student/subject" , "add" );
    }
}

 

 两种方法结果都为:


 

 Example2:

viewcache2.xml:

<?xml version="1.0" encoding="UTF-8" ?>  
<viewcache>  
    <areas>  
        <area id="1098" parentId="1001" areaType="province" name="上海" ordering="1867" phoneArea="111"/> 
        <area id="1099" parentId="1098" areaType="capital" name="北京" ordering="1868" phoneArea="010"/>
    </areas>  
</viewcache> 

 

package digester;
import java.util.ArrayList;
import java.util.List;

public class ViewCache {  
    private ArrayList<Area> areaList             = new ArrayList<Area>();  

    
    public ArrayList getAreaList() {
		return areaList;
	}


	public void setAreaList(ArrayList areaList) {
		this.areaList = areaList;
	}


	// 供Digester调用的方法  
    public void addArea(Area area) {  
    	System.out.println("addArea..");
        this.areaList.add(area);  
    }  
}  

 

package digester;

public class Area {  
    private int    id;  
    private String name;  
    private String areaType;  
    private int    parentId;  
    private int    ordering;  
//    private String zip;  
      
    private String phoneArea;

    public Area(){
    	System.out.println("Area constructor..");
    }
    
	public int getId() {
		return id;
	}

	public void setId(int id) {
		System.out.println( " set id of Area:" + id);
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		System.out.println( " set name of Area:" + name);
		this.name = name;
	}

	public String getAreaType() {
		return areaType;
	}

	public void setAreaType(String areaType) {
		System.out.println( " set areaType of Area:" + areaType);
		this.areaType = areaType;
	}

	public int getParentId() {
		return parentId;
	}

	public void setParentId(int parentId) {
		System.out.println( " set parentId of Area:" + parentId);
		this.parentId = parentId;
	}

	public int getOrdering() {
		return ordering;
	}

	public void setOrdering(int ordering) {
		System.out.println( " set ordering of Area:" + ordering);
		this.ordering = ordering;
	}

	/*public String getZip() {
		return zip;
	}

	public void setZip(String zip) {
		this.zip = zip;
	}*/

	public String getPhoneArea() {
		return phoneArea;
	}

	public void setPhoneArea(String phoneArea) {
		System.out.println( " set phoneArea of Area:" + phoneArea);
		this.phoneArea = phoneArea;
	}  
    
    
}

 

package digester;
import java.io.IOException;

import org.apache.tomcat.util.digester.Digester;
import org.xml.sax.SAXException;

public class AreaDigester {  
      
    public ViewCache digester() throws Exception {  
        Digester digester = new Digester();  
        digester.setValidating(false);  
        digester.addObjectCreate("viewcache/areas", ViewCache.class);  
        // 指明匹配模式和要创建的类   
        digester.addObjectCreate("viewcache/areas/area", Area.class);  
        
        //使用这句可以打印出Area字段set值时的syso语句,下面的打印不出,没搞清楚。。。
        digester.addSetProperties("viewcache/areas/area");  
       
//        digester.addSetProperties("viewcache/areas/area/id");  
//        digester.addSetProperties("viewcache/areas/area/parentId", "parentId", "parentId");  
//        digester.addSetProperties("viewcache/areas/area/name", "name", "name");  
//        digester.addSetProperties("viewcache/areas/area/areaType", "areaType", "areaType");  
//        digester.addSetProperties("viewcache/areas/area/ordering", "ordering", "ordering");  
//        //digester.addSetProperties("viewcache/areas/area/zip", "zip", "zip");  
//        digester.addSetProperties("viewcache/areas/area/phoneArea", "phoneArea", "phoneArea");  

        // 当移动到下一个标签中时的动作  
        digester.addSetNext("viewcache/areas/area", "addArea");  
          
        ViewCache vc = null;  
        try {  
            vc = (ViewCache) digester.parse("../apache-tomcat-6.0.41-src/test/viewcache2.xml");  
        } catch (IOException e) {  
            throw new Exception(e);  
        } catch (SAXException e) {  
            throw new Exception(e);  
        }  
        return vc;  
    }  
    
    public static void main(String[] args) {
		AreaDigester m = new AreaDigester();
		ViewCache vc = null;
		try {
			vc = m.digester();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}  

 结果:



 

 

 

 

 

  • 大小: 9.3 KB
  • 大小: 11.2 KB
分享到:
评论

相关推荐

    java反射,Digester解析xml文档

    java反射,Digester解析xml文档

    使用Digester解析XML文档示例

    使用Digester解析XML文档示例

    digester解析XML文件实例

    这是一个JAVA工程,导入后可直接运行,主要演示如何用digester解析XML文件

    使用Apache的Digester来解析XML文档

    使用Apache的Digester来解析XML文档,代码,有解析!

    Digester解析XML问题.pdf

    Digester解析XML问题.pdf

    Digester解析XML的小例子(对象嵌套)

    使用STRUTS的解析XML技术digester来解析多层嵌套的XML文件,简单易懂

    使用digester配置rule.xml规则来解析自定义的xml文件-代码

    使用digester配置rule.xml规则来解析自定义的xml文件

    Digester 实例

    首先Digester是什么,它是用来解析xml文件的的工具,是jakarta开源项目下commons的一个子项目,它能让程序员更方便的解析xml文件,而不需要了解底层的工作细节。 Digester 解析xml文件 实例。

    扩展PlugIn插件解析XML

    接口利用Digester类解析Xml文件为对象 个人感觉简单易懂,如有问题,还请多多指教。

    Digester_object

    测试利用Digester解析xml文件的java代码源码文件,包括:server.java、service.java、Engine.java、Listener.java和DigesterServer.java。

    digester jar 包

    java 解析xml文件 digester 将xml转换为java数据 digester jar 包

    digester解析实例

    实现XML解析好方法,使用digester效果比DOM,SAX解析更有效。当然对于小文件尽量不用digester.

    Jakarta-Common-Digester使用笔记

    我们无须了解SAX和DOM的解析过程,只要给Digester添加一些解析规则,就能对一个xml文件进行解析。Digester使用堆栈来保存xml节点(stack.push()方法),当该xml节点中嵌套的所有子节点解析完毕,该节点将被弹出...

    Digester笔记

    首先Digester是什么,它是用来解析xml文件的的工具,是jakarta开源项目下commons的一个子项目,它能让程序员更方便的解析xml文件,而不需要了解底层的工作细节。 如果要使用Digester作为xml文件的解析,请到jakarta...

    digester

    digester解析xml的全套组件,分别为digester-1.8, collections-3.2, beanutils-1.7.0, logging- &lt;br&gt;1.1.1。4个包里的jar文件已放在了一起,方便使用者导入,使用者亦可通过前缀区别组件。另外,jar &lt;br&gt;和...

    用到digester项目,直接解析存入数据库

    解析使用的xml文件在"参与者基础数据-4月.zip",sql语句就不贴了,如果是测试digester只需将dao层改一下,不要连接数据库,不同数据库创表好麻烦,如果需要存入数据库可以自行创建。

    JOX实现XML和JavaBean相互转化

    XML和JavaBean相互转化是一个非常有用的工作,用来读写xml的组件很多,比如dom4j, sax, JDom,Digester等,但是很多组件用起来很麻烦,今天给大家推荐一个超级简单的组件JOX, JOX是一套用户XML document和Java ...

    dom4j解析天气预报

    实现XML解析好方法,使用dom4j效果比DOM,SAX解析更有效。当然对于小文件尽量不用digester.

    开发自己一套struts框架

    此项目是为了更深入的理解MVC模式以及Struts的工作流程而开发的,运用了第三方commons组件, commons-digester来解析xml文件,把配置信息全部封装成类,然后运用MVC的思想去做相应的操作.

Global site tag (gtag.js) - Google Analytics