0

0

实体类与xml文件怎么转换

php中世界最好的语言

php中世界最好的语言

发布时间:2018-03-31 10:01:22

|

1630人浏览过

|

来源于php中文网

原创

这次给大家带来实体类与xml文件怎么转换,实体类与xml文件转换的注意事项有哪些,下面就是实战案例,一起来看一下。

最近写一个题目,要求将一组员工实体类转换成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  void writeXML(List 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 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  List getEntitys(Class c, String filePath) throws UnsupportedEncodingException, FileNotFoundException {
  return getEntitys(c, filePath, "utf-8");
 }
 /**
  * 将一个xml文件转变成实体类
  * @param c
  * @param filePath
  * @return
  * @throws FileNotFoundException 
  * @throws UnsupportedEncodingException 
  */
 public static  List getEntitys(Class c, String filePath, String encoding) throws UnsupportedEncodingException, FileNotFoundException {
  File file = new File(filePath);
  String labelName = c.getSimpleName().toLowerCase();
  SAXReader reader = new SAXReader();
  List 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();
   for(Iterator 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 getEntity(Class 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文件格式如下:



 
 1
 张三
 50
 25
 
 6
 9000.0
 
 
 2
 李四
 50
 22
 
 6
 8000.0
 

假如有个实体类如下:

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文件如下



 
 
 pcq
 18
 
 

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

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

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

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

AJAX如何检测用户名是否具有重复性

倍塔塞司
倍塔塞司

AI职业规划、AI职业测评、定制测评、AI工具等多样化职业类AI服务。

下载

用Ajax如何验证邮箱、用户名的唯一性

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

2

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

0

2026.01.31

Golang人工智能合集
Golang人工智能合集

本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

1

2026.01.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

76

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

73

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

67

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

19

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
NumPy 教程
NumPy 教程

共44课时 | 3万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号