Digester是apache的一个xml解析工具。

最近研究struts1源码时候才发现这东西挺好用的,可以很轻松的把XML转化成java对象。

上代码

public class Acptrule {
	private String id;
	private List<Rule> rules=new ArrayList<Rule>();
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public List<Rule> getRules() {
		return rules;
	}
	public void setRules(List<Rule> rules) {
		this.rules = rules;
	}
	public void addRule(Rule r){
		rules.add(r);
	}
	public String toString(){
		return "Acptrule:[id="+id+",\nrules:"+rules+"\n]";
	}
}
public class Rule {
	private String type;
	private List<Round> rounds=new ArrayList<Round>();
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public List<Round> getRounds() {
		return rounds;
	}
	public void setRounds(List<Round> rounds) {
		this.rounds = rounds;
	}
	public void addRound(Round r){
		rounds.add(r);
	}
	public String toString(){
		return "Rule:[type="+type+",\nrounds:"+rounds+"\n]";
	}
}
public class Round {
	private String val;
	private String allowed;
	private List<Noteinfo> notes=new ArrayList<Noteinfo>();
	public String getVal() {
		return val;
	}
	public void setVal(String val) {
		this.val = val;
	}
	public String getAllowed() {
		return allowed;
	}
	public void setAllowed(String allowed) {
		this.allowed = allowed;
	}
	public List<Noteinfo> getNotes() {
		return notes;
	}
	public void setNotes(List<Noteinfo> notes) {
		this.notes = notes;
	}
	public void addNoteinfo(Noteinfo i){
		notes.add(i);
	}
	public String toString(){
		return "Round:[val="+val+",allowed="+allowed+",\nnotes:"+notes+"\n]";
	}
}
public class Noteinfo {
	private String notetype;
	private String dcflag;
	public String getNotetype() {
		return notetype;
	}
	public void setNotetype(String notetype) {
		this.notetype = notetype;
	}
	public String getDcflag() {
		return dcflag;
	}
	public void setDcflag(String dcflag) {
		this.dcflag = dcflag;
	}
	public String toString(){
		return "Noteinfo:[notetype="+notetype+",dcflag="+dcflag+"]";
	}
}

以上是定义的几个java类。

下面是XML文件

<?xml version='1.0' encoding='gb18030'?>
<acptrule id='20000000'>
	<rule type='C'>
		<round val='0' allowed='N'>
			<noteinfo type='02' dcflag='1' />
			<noteinfo type='05' dcflag='1' />
			<noteinfo type='10' dcflag='1' />
			<noteinfo type='11' dcflag='1' />
			<noteinfo type='19' dcflag='1' />
			<noteinfo type='27' dcflag='1' />
			<noteinfo type='31' dcflag='1' />
			<noteinfo type='32' dcflag='1' />
			<noteinfo type='33' dcflag='1' />
			<noteinfo type='34' dcflag='1' />
			<noteinfo type='72' dcflag='1' />
			<noteinfo type='74' dcflag='1' />
		</round>
	</rule>
</acptrule>

解析代码

public static void main(String[] args) throws SQLException, IOException,
			SAXException {
		//读文件
		URL url=Test.class.getClassLoader().getResource("20000.xml");
		BufferedReader br = new BufferedReader(new FileReader(url.getPath()));
		String line=null;
		StringBuffer xml=new StringBuffer();
		while((line=br.readLine())!=null){
			xml.append(line);
		}
		//getRuleFromXML解析方法
		Acptrule r = (Acptrule) getRuleFromXML(xml.toString());
		System.out.println(r);
		br.close();

}
//Digester解析
public static Acptrule getRuleFromXML(String xml) throws IOException,
			SAXException {
	Digester d = new Digester();
	//不校验
	d.setValidating(false);
        //主要是通过RuleSet来做解析,网上大部分资料都是调用Degister.addXXX方法来实现的
        //RuleSet相当于一个Rule的集合。在addRuleInstances方法里,可以自己设计各种Rule,实际上效果和addXXX相当。好处就是把Rule和某个Digester分离
	RuleSet rs = new RuleSet() {
		@Override
		public String getNamespaceURI() {
			return null;
		}
		@Override
		public void addRuleInstances(Digester d) {
		    //对象创建Rule
		    d.addRule("acptrule", new ObjectCreateRule(Acptrule.class));
		    d.addRule("acptrule/rule", new ObjectCreateRule(Rule.class));
		    d.addRule("acptrule/rule/round", new ObjectCreateRule(Round.class));
		    d.addRule("acptrule/rule/round/noteinfo", new ObjectCreateRule(
			Noteinfo.class));
		    //当解析acptrule/rule完成后,调用xx方法的rule
		    d.addRule("acptrule/rule", new SetNextRule("addRule"));
		    d.addRule("acptrule/rule/round", new SetNextRule("addRound"));
        	    d.addRule("acptrule/rule/round/noteinfo", new SetNextRule(
			"addNoteinfo"));
		    //属性赋值rule(标签的attribute)
		    d.addRule("acptrule", new SetPropertiesRule("id", "id"));
		    d.addRule("acptrule/rule",new SetPropertiesRule("type", "type"));
		    d.addRule("acptrule/rule/round", new SetPropertiesRule("val",
			"val"));
    		    d.addRule("acptrule/rule/round", new SetPropertiesRule(
			"allowed", "allowed"));
		    d.addRule("acptrule/rule/round/noteinfo",
			new SetPropertiesRule("type", "notetype"));
		    d.addRule("acptrule/rule/round/noteinfo",
			new SetPropertiesRule("dcflag", "dcflag"));
			}
		};
		d.addRuleSet(rs);
		return (Acptrule) d.parse(new StringReader(xml));
	}