用分治法解决级联对象与相应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 >
< 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;
}
}
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;
}
}
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;
}
}
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();
}
}
}
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