2014-09-30 73 views
0

有人可以帮助我使用Digester API从下面的XML文件创建Java对象。使用Digester从XML文件创建Java对象

我有一类公司有地图这样

Map<String,Department> nameToDeptMap= new HashMap<String,Department>(); 

我想下面的XML数据加载到该地图。

 Department is super class. Development,Testing,Requirment...etc are extending that class. 


    <Company> 
    <Employee empname="xyz" department ="com.compnayname.departments.department.Development> 
    <Employee empname="xyza" department ="com.compnayname.departments.department.Testing> 
    <Employee empname="xyzab" department ="com.compnayname.departments.department.Requiremetns> 
    <Employee empname="xyzabc" department ="com.compnayname.departments.department.Production> 
    . 
    . 
    . 
    . 
    </Company> 

当Map加载时,我会通过“empname”来获取部门对象。

如果你想知道我在做什么,请参阅下面的代码。我知道这是错误的。

我的Java文件是这样的..

我能写沼气池规则,以获得从XML文件作为字符串的值,但不知道怎么弄的对象。

Digester digester = new Digester();  
    digester.addObjectCreate("Company/Employee", Company.class);   
    digester.addCallMethod("Company/Employee", "setComapnyConfigMap", 2); 
    digester.addCallParam("Company/Employee", 0, "empname"); 
    digester.addCallParam("Company/Employee", 1, "department"); 


      :> Using JDK 1.6 , commons-digester-2.0. 

回答

0

这不是沼气池打算做:

“很多项目读取XML配置文件在系统内提供各种Java对象的初始化有这样做的几种方法,以及沼气池组件旨在提供可用于许多不同项目的通用实现。“

你想要做的事情是使用XStream甚至DOM解析(jdom或dom4j)这样的东西来实现更容易。

+0

确定。感谢您的回应。等着瞧。 – 2014-09-30 17:13:30

+0

@Larry:我认为这正是Digester设计的目标:解析XML并根据模式匹配触发提供的或自定义的规则。您引用的那一段的下一段: “基本上,Digester包允许您配置一个XML - > Java对象映射模块,只要识别出嵌套的XML元素的特定模式,就会触发某些称为规则的操作。的预定义规则可供您使用,或者您也可以创建自己的规则。“ – Barney 2014-10-11 10:25:44

+0

”许多项目读取** XML配置文件**以提供系统内各种Java对象的初始化。有几种方法可以做到这一点,而Digester组件旨在提供一个可用于许多不同项目的通用实现。“ – Larry 2014-10-12 11:32:55

0

我不完全清楚你想在这里实现什么:你是否需要为每个员工创建一个新的Department实例,或者你是否试图将员工id映射到现有部门?无论采用哪种方式,都有很多方法可以与Digester一起完成此操作,但如果您是Digester的新手,最简单的方法就是更新您的setComapnyConfigMap方法以接受字符串参数,然后在其中执行whaatever。例如,要创建特定的部门子类的新实例为每个员工:

public static class Company { 
    private Map<String, Department> nameToDeptMap = new HashMap<>(); 

    public void setComapnyConfigMap(String empName, String deptClass) 
     throws InstantiationException, IllegalAccessException, ClassNotFoundException { 

    Department dept = (Department)Class.forName(deptClass).newInstance(); 
    nameToDeptMap.put(empName, dept); 
    } 
} 

那么你的沼气池代码是因为你已经拥有了它:

String xml = "<Company>" 
     + "<Employee empname='xyz' department ='com.compnayname.departments.department.Development'/>" 
     + "<Employee empname='xyza' department='com.compnayname.departments.department.Testing'/>" 
     + "<Employee empname='xyzab' department='com.compnayname.departments.department.Requirements'/>" 
     + "<Employee empname='xyzabc' department='com.compnayname.departments.department.Production'/>" 
     + "</Company>"; 

    Digester digester = new Digester(); 
    digester.addObjectCreate("Company/Employee", Company.class); 
    digester.addCallMethod("Company/Employee", "setComapnyConfigMap", 2); 
    digester.addCallParam("Company/Employee", 0, "empname"); 
    digester.addCallParam("Company/Employee", 1, "department"); 

    Company c = digester.parse(new StringReader(xml)); 

如果要映射的员工一个特定的部门,让消化代码保持不变,只是改变Company.setComapnyConfigMap方法的内容。

(我使用JDK7 /沼气池3,但它应该是在JDK6 /沼气池2罚款)

干杯,