用户登录
用户注册

分享至

简单实体类和xml文件的相互转换方法

  • 作者: 孔子见两小儿便日_
  • 来源: 51数据库
  • 2021-08-10

最近写一个题目,要求将一组员工实体类转换成xml文件,或将xml文件转换成一组实体类。题目不难,但写完感觉可以利用泛型和反射将任意一个实体类和xml文件进行转换。于是今天下午立马动手

试了下,做了个简单的模型,可以将简单的实体类和xml文件进行相互转换,但对实体类的属性类型有限制,目前只支持string, integer, double三种类型。但是后面可以扩展。

我的大概思路是这样的,只要能拿到实体类的类型信息,我就能拿到实体类的全部字段名称和类型,拼属性的set和get方法更是简单明了,这时候只需要通过方法的反射,将xml文件的数据读取出来给这个反射即可。

反过来只要给我一个任意对象,我就能通过反射拿到该对象所有字段的值,这时候在写xml文件即可。

具体代码如下:

package com.pcq.entity;

import java.io.*;
import java.lang.reflect.field;
import java.lang.reflect.invocationtargetexception;
import java.lang.reflect.method;
import java.util.arraylist;
import java.util.iterator;
import java.util.list;

import org.dom4j.document;
import org.dom4j.documentexception;
import org.dom4j.documenthelper;
import org.dom4j.element;
import org.dom4j.io.outputformat;
import org.dom4j.io.saxreader;
import org.dom4j.io.xmlwriter;

public class xmlandentityutil {
 private static document document = documenthelper.createdocument();
 
 /**
  * 判断是否是个xml文件,目前类里尚未使用该方法
  * @param filepath 
  * @return
  */
 @suppresswarnings("unused")
 private static boolean isxmlfile(string filepath) {
  file file = new file(filepath);
  if(!file.exists() || filepath.indexof(".xml") > -1) {
   return false;
  }
  return true;
 }
 
 /**
  * 将一组对象数据转换成xml文件
  * @param list
  * @param filepath 存放的文件路径
  */
 public static <t> void writexml(list<t> list, string filepath) {
  class<?> c = list.get(0).getclass();
  string root = c.getsimplename().tolowercase() + "s";
  element rootele = document.addelement(root);
  for(object obj : list) {
   try {
    element e = writexml(rootele, obj);
    document.setrootelement(e);
    writexml(document, filepath);
   } catch (nosuchmethodexception | securityexception
     | illegalaccessexception | illegalargumentexception
     | invocationtargetexception e) {
    e.printstacktrace();
   }
  }
 }
 /**
  * 通过一个根节点来写对象的xml节点,这个方法不对外开放,主要给writexml(list<t> list, string filepath)提供服务
  * @param root
  * @param object
  * @return
  * @throws nosuchmethodexception
  * @throws securityexception
  * @throws illegalaccessexception
  * @throws illegalargumentexception
  * @throws invocationtargetexception
  */
 private static element writexml(element root, object object) throws nosuchmethodexception, securityexception, illegalaccessexception, illegalargumentexception, invocationtargetexception {
  class<?> c = object.getclass();
  string classname = c.getsimplename().tolowercase();
  element ele = root.addelement(classname);
  field[] fields = c.getdeclaredfields();
  for(field f : fields) {
   string fieldname = f.getname();
   string param = fieldname.substring(0, 1).touppercase() + fieldname.substring(1);
   element fieldelement = ele.addelement(fieldname);
   method m = c.getmethod("get" + param, null);
   string s = "";
   if(m.invoke(object, null) != null) {
    s = m.invoke(object, null).tostring();
   }
   fieldelement.settext(s);
  }
  return root;
 }
 
 /**
  * 默认使用utf-8
  * @param c
  * @param filepath
  * @return
  * @throws unsupportedencodingexception
  * @throws filenotfoundexception
  */
 public static <t> list<t> getentitys(class<t> c, string filepath) throws unsupportedencodingexception, filenotfoundexception {
  return getentitys(c, filepath, "utf-8");
 }
 /**
  * 将一个xml文件转变成实体类
  * @param c
  * @param filepath
  * @return
  * @throws filenotfoundexception 
  * @throws unsupportedencodingexception 
  */
 public static <t> list<t> getentitys(class<t> c, string filepath, string encoding) throws unsupportedencodingexception, filenotfoundexception {
  file file = new file(filepath);
  string labelname = c.getsimplename().tolowercase();
  saxreader reader = new saxreader();
  list<t> list = null;
   try {
   inputstreamreader in = new inputstreamreader(new fileinputstream(file), encoding);
   document document = reader.read(in);
   element root = document.getrootelement();
   list elements = root.elements(labelname);
   list = new arraylist<t>();
   for(iterator<emp> it = elements.iterator(); it.hasnext();) {
     element e = (element)it.next();
     t t = getentity(c, e);
     list.add(t);
    }
  } catch (documentexception e) {
   e.printstacktrace();
  } catch (instantiationexception e1) {
   e1.printstacktrace();
  } catch (illegalaccessexception e1) {
   e1.printstacktrace();
  } catch (nosuchmethodexception e1) {
   e1.printstacktrace();
  } catch (securityexception e1) {
   e1.printstacktrace();
  } catch (illegalargumentexception e1) {
   e1.printstacktrace();
  } catch (invocationtargetexception e1) {
   e1.printstacktrace();
  }
  return list;
 }
 
 
 /**
  * 将一种类型 和对应的 xml元素节点传进来,返回该类型的对象,该方法不对外开放
  * @param c 类类型
  * @param ele 元素节点
  * @return 该类型的对象
  * @throws instantiationexception
  * @throws illegalaccessexception
  * @throws nosuchmethodexception
  * @throws securityexception
  * @throws illegalargumentexception
  * @throws invocationtargetexception
  */
 @suppresswarnings("unchecked")
 private static <t> t getentity(class<t> c, element ele) throws instantiationexception, illegalaccessexception, nosuchmethodexception, securityexception, illegalargumentexception, invocationtargetexception {
  field[] fields = c.getdeclaredfields();
  object object = c.newinstance();//
  for(field f : fields) {
   string type = f.gettype().tostring();//获得字段的类型
   string fieldname = f.getname();//获得字段名称
   string param = fieldname.substring(0, 1).touppercase() + fieldname.substring(1);//把字段的第一个字母变成大写
   element e = ele.element(fieldname);
   if(type.indexof("integer") > -1) {//说明该字段是integer类型
    integer i = null;
    if(e.gettexttrim() != null && !e.gettexttrim().equals("")) {
     i = integer.parseint(e.gettexttrim());
    }
    method m = c.getmethod("set" + param, integer.class);
    m.invoke(object, i);//通过反射给该字段set值
   }
   if(type.indexof("double") > -1) { //说明该字段是double类型
    double d = null;
    if(e.gettexttrim() != null && !e.gettexttrim().equals("")) {
     d = double.parsedouble(e.gettexttrim());
    }
    method m = c.getmethod("set" + param, double.class);
    m.invoke(object, d);
   }
   if(type.indexof("string") > -1) {//说明该字段是string类型
    string s = null;
    if(e.gettexttrim() != null && !e.gettexttrim().equals("")) {
     s = e.gettexttrim();
    }
    method m = c.getmethod("set" + param, string.class);
    m.invoke(object, s);
   }
  }
  return (t)object;
 }
 /**
  * 用来写xml文件
  * @param doc document对象
  * @param filepath 生成的文件路径
  * @param encoding 写xml文件的编码
  */
 public static void writexml(document doc, string filepath, string encoding) {
  xmlwriter writer = null;
  outputformat format = outputformat.createprettyprint();
  format.setencoding(encoding);// 指定xml编码  

  try {
   writer = new xmlwriter(new filewriter(filepath), format);
   writer.write(doc);
  } catch (ioexception e) {
   e.printstacktrace();
  } finally {
   try {
    writer.close();
   } catch (ioexception e) {
    e.printstacktrace();
   }
  }
 }
 
 /**
  * 默认使用utf-8的格式写文件
  * @param doc
  * @param filepath
  */
 public static void writexml(document doc, string filepath) {
  writexml(doc, filepath, "utf-8");
 }
}

假如有个实体类是:

package com.pcq.entity;

import java.io.serializable;

public class emp implements serializable{

 private integer id;
 private string name;
 private integer deptno;
 private integer age;
 private string gender;
 private integer bossid;
 private double salary;
 public integer getid() {
  return id;
 }
 public void setid(integer id) {
  this.id = id;
 }
 public string getname() {
  return name;
 }
 public void setname(string name) {
  this.name = name;
 }
 public integer getdeptno() {
  return deptno;
 }
 public void setdeptno(integer deptno) {
  this.deptno = deptno;
 }
 public integer getage() {
  return age;
 }
 public void setage(integer age) {
  this.age = age;
 }
 public string getgender() {
  return gender;
 }
 public void setgender(string gender) {
  this.gender = gender;
 }
 public integer getbossid() {
  return bossid;
 }
 public void setbossid(integer bossid) {
  this.bossid = bossid;
 }
 public double getsalary() {
  return salary;
 }
 public void setsalary(double salary) {
  this.salary = salary;
 }
 
}

那么写出来的xml文件格式如下:

<?xml version="1.0" encoding="utf-8"?>

<emps>
 <emp>
 <id>1</id>
 <name>张三</name>
 <deptno>50</deptno>
 <age>25</age>
 <gender>男</gender>
 <bossid>6</bossid>
 <salary>9000.0</salary>
 </emp>
 <emp>
 <id>2</id>
 <name>李四</name>
 <deptno>50</deptno>
 <age>22</age>
 <gender>女</gender>
 <bossid>6</bossid>
 <salary>8000.0</salary>
 </emp>
</emps>

假如有个实体类如下:

package com.pcq.entity;

public class student {

 private integer id;
 private string name;
 private integer age;
 private string gender;
 public integer getid() {
  return id;
 }
 public void setid(integer id) {
  this.id = id;
 }
 public string getname() {
  return name;
 }
 public void setname(string name) {
  this.name = name;
 }
 public integer getage() {
  return age;
 }
 public void setage(integer age) {
  this.age = age;
 }
 public string getgender() {
  return gender;
 }
 public void setgender(string gender) {
  this.gender = gender;
 }
 
}

那么写出来的xml文件如下

<?xml version="1.0" encoding="utf-8"?>

<students>
 <student>
 <id></id>
 <name>pcq</name>
 <age>18</age>
 <gender>男</gender>
 </student>
</students>

读取也必须读这种格式的xml文件,才能转换成实体类,要求是实体类的类类型信息(class)必须要获得到。

另外这里的实体类的属性类型均是integer,string,double,可以看到工具类里只对这三种类型做了判断。而且可以预想的是,如果出现一对多的关系,即一个实体类拥有一组另一个类对象的引用,

那xml和实体类的相互转换要比上述的情况复杂的多。lz表示短时间内甚至长时间内也不一定能做的出来,欢迎同道高人指点。

以上这篇简单实体类和xml文件的相互转换方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

软件
前端设计
程序设计
Java相关