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)); }