春风博客

春天里,百花香...

导航

<2007年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

统计

公告

MAIL: junglesong@gmail.com
MSN: junglesong_5@hotmail.com

Locations of visitors to this page

常用链接

留言簿(11)

随笔分类(224)

随笔档案(126)

个人软件下载

我的其它博客

我的邻居们

最新随笔

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜

用分治法解决级联对象与相应XML之间的互相转化问题

如果我们有一个group对象,它底下有一堆company对象,company底下有一堆employee对象,我们可称这三个对象为级联对象,如果要求将对象从以下
XML文件中转化过来该怎么做呢?
<?xml version="1.0" encoding="UTF-8"?>
<root>
    
<group name="citigroup">
        
<location>New york</location>
        
<company name="citibank">
            
<location>Paris</location>
            
<employee name="andy">
                
<age>29</age>
            
</employee>
            
<employee name="bill">
                
<age>30</age>
            
</employee>
            
<employee name="cindy">
                
<age>31</age>
            
</employee>
        
</company>
        
<company name="citisoft">
            
<location>Dalian</location>
            
<employee name="doll">
                
<age>32</age>
            
</employee>
            
<employee name="edin">
                
<age>33</age>
            
</employee>
            
<employee name="felix">
                
<age>34</age>
            
</employee>
        
</company>
    
</group>
</root>

如果集中解析XML的话,解析XML的代码和创建对象的代码将混杂在在一块,级联关系越深,代码将越冗长难懂而难以修改,使代码可维护性不佳;

如果我们让一个对象与相应的XML节点关联起来的话,只需要在构造函数中处理有关部分的XML.拿Group对象举例来说,它只需要知道如何从一个<group>...</group>节点中提取name,location以及下级的company就行了,从XML的角度来说,它只需要辨认<group>节点下的<name>属性,<location>子节点和<company>子节点就行了,转化为对象时只需转化这些内容,而下级节点如<company>的内容则交给Company类去处理.对一个类来说,它只需要知道和成员变量有关的节点就行了,其它部分自有上级或下级类处理,这样一层层分治开来,代码结构将清晰和简化起来.

下面是代码,请注意观察下面Group,Company,Employee三个类的构造函数:

Group类:
package com.sitinspring.objectxml;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;

public class Group {
    
private String name;

    
private String location;

    
private List<Company> companies;

    
public Group(Element element){
        
this.name=element.attributeValue("name");
        
this.location=element.elementText("location");
        
        companies
=new ArrayList<Company>();
        List companyNodes 
= element.elements("company");        
        
for (Iterator it = companyNodes.iterator(); it.hasNext();) {
            Element companyElm 
= (Element) it.next();
            companies.add(
new Company(companyElm));
        }

    }

    
    
public Element makeElement(Element parentElm){
        Element element
=parentElm.addElement("group");
        
        element.addAttribute(
"name"this.name);
        Element ageElm 
= element.addElement("location");
        ageElm.setText(
this.location);
        
        
for (Iterator it = companies.iterator(); it.hasNext();) {
            Company company 
= (Company) it.next();
            
            company.makeElement(element);
        }

        
        
return element;
    }

    
    
public List<Company> getCompanies() {
        
return companies;
    }


    
public String getLocation() {
        
return location;
    }


    
public void setLocation(String location) {
        
this.location = location;
    }


    
public String getName() {
        
return name;
    }


    
public void setName(String name) {
        
this.name = name;
    }

}

Company类:
package com.sitinspring.objectxml;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;

public class Company {
    
private String name;

    
private String location;

    
private List<Employee> employees;

    
public Company(Element element){
        
this.name=element.attributeValue("name");
        
this.location=element.elementText("location");
        
        employees
=new ArrayList<Employee>();
        List employeeNodes 
= element.elements("employee");        
        
for (Iterator it = employeeNodes.iterator(); it.hasNext();) {
            Element employeeElm 
= (Element) it.next();
            employees.add(
new Employee(employeeElm));
        }

    }

    
    
public Element makeElement(Element parentElm){
        Element element
=parentElm.addElement("company");
        
        element.addAttribute(
"name"this.name);
        Element ageElm 
= element.addElement("location");
        ageElm.setText(
this.location);
        
        
for (Iterator it = employees.iterator(); it.hasNext();) {
            Employee employee 
= (Employee) it.next();
            employee.makeElement(element);
        }

        
        
return element;
    }

    
    
public String getLocation() {
        
return location;
    }


    
public void setLocation(String location) {
        
this.location = location;
    }


    
public String getName() {
        
return name;
    }


    
public void setName(String name) {
        
this.name = name;
    }


    
public List<Employee> getEmployees() {
        
return employees;
    }


    
public void setEmployees(List<Employee> employees) {
        
this.employees = employees;
    }

}

Employee类:
package com.sitinspring.objectxml;

import org.dom4j.Element;

public class Employee {
    
private String name;

    
private int age;

    
public Employee(Element element) {
        
this.name = element.attributeValue("name");
        
this.age = Integer.parseInt(element.elementText("age"));
    }


    
public Element makeElement(Element parentElm) {
        Element element 
= parentElm.addElement("employee");

        element.addAttribute(
"name"this.name);
        Element ageElm 
= element.addElement("age");
        ageElm.setText(String.valueOf(
this.age));

        
return element;
    }


    
public int getAge() {
        
return age;
    }


    
public void setAge(int age) {
        
this.age = age;
    }


    
public String getName() {
        
return name;
    }


    
public void setName(String name) {
        
this.name = name;
    }

}

从上面三个构造函数我们可以发现,传入一个节点,程序会解析这个节点并生成一个对象.

从对象生成XML是构造函数的逆过程,思想是一样的,这里就不赘述了,大家观察三个类中的makeElement函数即可.

调用过程:
package com.sitinspring.objectxml;

import java.io.File;
import java.io.FileWriter;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class Test{
    
public static void main(String[] args){
        
try{
            
// 从XML得到对象
            SAXReader reader = new SAXReader();
            Document document
= reader.read(new File("group1.xml"));
            Element groupElm
=document.getRootElement().element("group");
            Group group
=new Group(groupElm);
            
            
// 从对象得到XML
            Document document2 = DocumentHelper.createDocument();
            Element root 
= document2.addElement("root");
            Element groupElm2
=group.makeElement(root);

            XMLWriter writer 
= new XMLWriter(new FileWriter("group2.xml"));
            writer.write(document2);
            writer.close();
        }

        
catch(Exception ex){
            ex.printStackTrace();
        }

    }

}

源码下载(请大家自行加入dom4j包):
http://www.blogjava.net/Files/sitinspring/ObjectXml20070917002818.rar

posted on 2007-09-17 00:25 sitinspring 阅读(1321) 评论(4)  编辑  收藏 所属分类: Object Orient Programming

评论

# re: 用分治法解决级联对象与相应XML之间的互相转化问题 2007-09-17 09:54 千里冰封

不错,学习了
不过,JDK里面不是有操作XML的包吗,为什么要用一个非标准的包呢  回复  更多评论   

# re: 用分治法解决级联对象与相应XML之间的互相转化问题 2007-09-17 09:59 sitinspring

@千里冰封

以前做项目习惯用dom4j了,再之前用jdom.1.5以前的dom或sax没他们俩这么方便,1.5以后就不清楚了.你有什么更好的推荐吗?



  回复  更多评论   

# re: 用分治法解决级联对象与相应XML之间的互相转化问题 2007-09-17 13:11 惊鸿逝水

XStream可以实现你想要的 ,应该比Dom4j更好  回复  更多评论   

# re: 用分治法解决级联对象与相应XML之间的互相转化问题 2007-09-17 13:17 sitinspring

@惊鸿逝水

谢谢指教.  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
sitinspring(http://www.blogjava.net)原创,转载请注明出处.