最近看看tomcat的源码实现,发现将xml解析为java对象使用了 Digester;故而学习一下;
Digester 通过递归的思想解决xml的解析;使用Stack 的堆栈结构,xml解析的时候,主要关注 begin(开始一个标签) 和 end(结束一个标签) 事件;
begin:创建对象并入栈;
end:对象出栈;
在begin 和 end 之间,我们可以设置对象(栈顶)属性,并将栈顶的下一个对象与当前栈顶对象建立父子关系(一对一或一对多;与xml中父子节点定义一致);
xml节点的匹配使用pattern ,支持模糊匹配; (节点之间使用/分割)
事件 使用预先定义的Rule;
具体请看下例:
<system>
<ams attr="attr-A" attrKey="propertyRule" attrValue="propertyRuleValue">
<name>供应商管理</name>
</ams>
<dmc realClass="Dmc_B">
<name>数据中心</name>
</dmc>
</system>
解析以上的xml 并转为 System 的对象
定义如下的类:
<system> 对应的类
public class System {
private Ams ams;
private Dmc dmc;
public Ams getAms() {
return ams;
}
public void setAms(Ams ams) {
this.ams = ams;
}
public Dmc getDmc() {
return dmc;
}
public void setDmc(Dmc dmc) {
this.dmc = dmc;
}
@Override
public String toString() {
return "System [ams=" + ams + ", dmc=" + dmc + "]";
}
}
<ams> 对应的类
public class Ams {
private System system;
public void setSystem(System system) {
this.system = system;
}
private String name;
private String attr;
private String propertyRule;
public void setPropertyRule(String propertyRule) {
this.propertyRule = propertyRule;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAttr(String attr) {
this.attr = attr;
}
@Override
public String toString() {
return "Ams [system=" + (null==system?null:system.hashCode()) + ", name=" + name + ", attr=" + attr + ", propertyRule=" + propertyRule + "]";
}
}
<dmc> 对应的类 有三个 abstract 的Dmc、继承Dmc 的 Dmc_A、Dmc_B
public abstract class Dmc {
private String name;
public Dmc(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dmc [name=" + name + "]";
}
}
public class Dmc_A extends Dmc {
public Dmc_A(String name) {
super(name);
}
@Override
public String toString() {
return "Dmc_A [getName()=" + getName() + "]";
}
}
public class Dmc_B extends Dmc{
public Dmc_B(String name) {
super(name);
}
@Override
public String toString() {
return "Dmc_B [getName()=" + getName() + "]";
}
}
自定义的DmcObjectCreationFactory
public class DmcObjectCreationFactory extends AbstractObjectCreationFactory<Dmc> {
@Override
public Dmc createObject(Attributes attributes) throws Exception {
String realClass = attributes.getValue("realClass");
if("Dmc_A".equals(realClass)) {
return new Dmc_A("默认名称");
} else if("Dmc_B".equals(realClass)) {
return new Dmc_B("默认名称");
}
return null;
}
}
测试类
public class DigesterTest {
public static void main(String[] args) throws IOException, SAXException {
Rule ruleA = new ObjectCreateRule(com.hym.digester.bean.System.class);
Rule ruleB = new ObjectCreateRule(com.hym.digester.bean.Ams.class);
Rule ruleC = new SetNextRule("setAms", com.hym.digester.bean.Ams.class);
Rule ruleF = new SetTopRule("setSystem", com.hym.digester.bean.System.class);
Rule ruleD = new SetPropertiesRule();
Rule ruleE = new SetPropertyRule("attrKey", "attrValue");
Rule ruleG = new FactoryCreateRule(DmcObjectCreationFactory.class);
Rule ruleH = new SetNextRule("setDmc", com.hym.digester.bean.Dmc.class);
Digester digester = new Digester();
digester.addRule("system", ruleA);
digester.addRule("system/ams", ruleB);
digester.addRule("system/ams", ruleC);
digester.addRule("system/ams", ruleD);
digester.addRule("system/ams", ruleE);
digester.addRule("system/ams", ruleF);
digester.addRule("system/dmc", ruleG);
digester.addRule("system/dmc", ruleH);
Object obj = digester.parse(new File("D:/WorkSpace/LearnDemo/src/resource/digester/System.xml"));
System.out.println(obj);
}
}