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