学习整理:dom4j解析xml

在学习的过程中,主要对节点元素、属性、属性值、内容等区别上理解的不够明确,导致第一次使用时,修改了多次。所以以此来总结和记录学习过程

 

解析xml,主要先通过获取到Document对象,然后根据对象获取到各个节点和节点的属性等。

 

 

示例xml内容:

 

<?xml version="1.0" encoding="UTF-8"?>
<struts>
    <action name="login" class="com.coderising.litestruts.LoginAction">
        <result name="success">/jsp/homepage.jsp</result>
        <result name="fail">/jsp/showLogin.jsp</result>
    </action>
    <action name="logout" class="com.coderising.litestruts.LogoutAction">
        <result name= "success">/jsp/welcome.jsp</result>
        <result name= "error">/jsp/error.jsp</result>
    </action>
</struts>

 

一、获取Document 对象

//通过创建SAXReader对象,根据xml文件,传入路径获取Document

SAXReader saxReader = new SAXReader();
Document document = saxReader.read(
new File("src/com/coderising/litestruts/struts.xml"));

 

二、获取根节点元素对象

Element root = document.getRootElement(); //这里就是struts

//获取所有一级子元素

List<Element> listElement=root.elements(); //两个action

//获取指定元素

Element actionElement = root.element(String str);

//这里都是action,所以可以先获取所有一级子元素后,遍历集合,通过name的属性值来选取所需的action

 

三、获取元素的属性、属性值及内容

这里以第一个action为例:

1nameclass是属性。相关的API

List<Attribute> list = element.attributes();//获取所有属性

Attribute attr = element.attribute("name");//获取name属性

attr.getName(); //得到name

 

2logincom.coderising.litestruts.LoginAction是属性值

attr.getValue(); //得到“login”

String classStr = element.attribute("class").getValue();

通过类似操作,得到class路径后就可以根据反射来创建对应的class类及对象,然后进行后续的操作。

 

3,要想获取 /jsp/homepage.jsp 内容,同前面的操作先获取第二级的子元素集合,再根据属性判断,获取想要的result,再根据getText()方法获取内容。

jspStr = resultElement.getText();

 

流程:这里解析xml的流程是一个简单的登陆流程。外部传入的参数例如是 login的登陆申请,同时传入 帐号密码信息。

通过login这个参数(也就是上面的例子),解析xml,得到第一个action,进而得到对应的class类。根据传入的帐号密码参数,结合反射,对该类进行操作。得到result结果。成功/失败,则进而得到对应的jsp页面。

 

--------------------------------------------------------------------------------------------------------

再继续记录下反射功能这部分吧。

假设传入的帐号密码是以map的形式:

Map<String,String> params = new HashMap<String,String>();

        params.put("name","test");

        params.put("password","1234");

并且假设对应的类中,有name,password字段,同时有message字段,

name = test,passowrd=1234 (伪代码) 时,返回 “success”

 

四、通过反射创建对象

Class<?> clazz = Class.forName(classStr); //即LoginAction 类

Object c = clazz.newInstance();  

 

五、运用反射把参数用类的set方法,传入进去。

//获取所有类的字段

Field[] fields = clazz.getDeclaredFields();

 

可以通过PropertyDescriptor getReadMethod()getWriteMethod()方法获取set/get方法。

通过查看API得知,添加set/get的同时会自动把属性名称的第一个字母改为大写。如果类写的比较规范,那么可以直接使用这两个方法,如果get/set方法名称比较特殊,可以自己写个方法。

//自己写了一个方法,来实现这个转换过程。

public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz,String propertyName) {  
        StringBuffer sb = new StringBuffer();
        Method setMethod = null;  
        Method getMethod = null;  
        PropertyDescriptor pd = null;  
        try {  
            Field f = clazz.getDeclaredField(propertyName);//根据字段名来获取字段  
            if (f!= null) {  
               //构建方法的后缀  
               String methodEnd = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);  
               sb.append("set" + methodEnd);
               setMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{f.getType()});  
               sb.delete(0, sb.length());//清空
               sb.append("get" + methodEnd);
               //构建get 方法  
               getMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{ });  
               //构建一个属性描述器 把对应属性 propertyName 的 get 和 set 方法保存到属性描述器中  
               pd = new PropertyDescriptor(propertyName, getMethod, setMethod);  
            }  
        } catch (Exception ex) {  
            ex.printStackTrace();  
        }  
      
        return pd;  
    } 

 

 

 六、遍历参数,把所有字段都通过set方法写入。

 

Set<Entry<String, String>> set = map.entrySet();

  for(Entry<String, String> entry : set){

    String key = entry.getKey();

    String val = entry.getValue();

    for(Field f :fields){

    PropertyDescriptor pd = new PropertyDescriptor(key, clazz);

    //这里也可以用自己写的方法
    //PropertyDescriptor pd = getPropertyDescriptor(clazz,key);

    Method setMethod = pd.getWriteMethod(); //获得用于读取属性值的方法
  
    setMethod.invoke(c, new Object[]{val});

  }

}

 

 

同理,set后可调用get方法,获取对象的信息进而进行后续操作。

 

-----------------------------------------------------------------------------------------------

 

这次学习告一段落,顺便记录下dom4j的几个其他常用api

 

节点操作:

Element newElement = element.addElement("newNode");

//为newNode节点设置值  

newElement.setText("新信息"); 

 

属性操作:

Attribute idAttribute = element.attribute("id");  

//删除其属性  

element.remove(idAttribute);  

//为其添加新属性  

element.addAttribute("name", "这是element节点的新属性");  

 

posted @ 2017-03-03 18:41  BlueK  阅读(220)  评论(0编辑  收藏  举报