XStream解析XML文本并用反射机制转换为对象

xml文本格式是网络通信中最常用的格式,最近特别研究了一下如何解析xml文本并转换为对象,现在分享一下我最近的学习成果~

先列一下本例中需要解析的xml文本:

Xml代码  

  1. <results name="list">
  2. <row pubtime="2016-04-13 16:40:13" author="APP"  id="140" title="什么是公告" content="公告,是公开宣告。" />
  3. <row pubtime="2016-04-13 16:36:50" author="网站" id="138" title="12345678" content="12345678"  />
  4. <row pubtime="2016-04-06 15:02:44" author="网站" id="134" title="关于网站用户注册流程说明1" content="关于用户注册流程说明"  />
  5. <row pubtime="2016-03-30 18:32:13" author="APP"  id="126" title="关于网站使用说明" content="测试"  />
  6. <row pubtime="2016-03-30 18:29:26" author="网站" id="125" title="关于手机App使用说明" content="123"  />
  7. </results>

讲一下我的思路,我选择使用XStream来解析xml文本,因为xstream在转换对象方面会比dom4j更优秀一些,它是通过注解方式来声明对应结点的,在操作上会更直观方便。首先会将整个文本转换成一个Results类对象,而每一个row结点作为一个HashMap放入到Results类对象的List列表中,最后会将每一个HashMap读取出来通过JAVA的反射机制转换为Info对象,并生成List列表。下载

Info类代码  

  1. public class Info {
  2. private String id;
  3. private String title;
  4. private String content;
  5. private String author;
  6. private String pubtime;
  7. public String getId() {
  8. return id;
  9. }
  10. public void setId(String id) {
  11. this.id = id;
  12. }
  13. public String getTitle() {
  14. return title;
  15. }
  16. public void setTitle(String title) {
  17. this.title = title;
  18. }
  19. public String getContent() {
  20. return content;
  21. }
  22. public void setContent(String content) {
  23. this.content = content;
  24. }
  25. public String getAuthor() {
  26. return author;
  27. }
  28. public void setAuthor(String author) {
  29. this.author = author;
  30. }
  31. public String getPubtime() {
  32. return pubtime;
  33. }
  34. public void setPubtime(String pubtime) {
  35. this.pubtime = pubtime;
  36. }
  37. @Override
  38. public String toString() {
  39. return "Info [author=" + author + ", content=" + content + ", id=" + id
  40. + ", pubtime=" + pubtime + ", title=" + title + "]";
  41. }
  42. }

Row类代码  

  1. @XStreamConverter(RowConverter.class)
  2. public class Row extends HashMap<String, String> {
  3. private static final long serialVersionUID = 5619951409573339302L;
  4. }  下载

Results代码  

  1. @XStreamAlias("results")
  2. public class Results {
  3. @XStreamAlias("name")
  4. @XStreamAsAttribute
  5. private String name;
  6. @XStreamImplicit(itemFieldName = "row")
  7. private List<Row> rows;
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. public List<Row> getRows() {
  15. return rows;
  16. }
  17. public void setRows(List<Row> rows) {
  18. this.rows = rows;
  19. }
  20. }

Rowconverter类代码  

  1. public class RowConverter extends AbstractCollectionConverter {
  2. public RowConverter(Mapper mapper) {
  3. super(mapper);
  4. // TODO Auto-generated constructor stub
  5. }
  6. @Override
  7. public boolean canConvert(Class arg0) {
  8. // TODO Auto-generated method stub
  9. return Row.class.equals(arg0);
  10. }
  11. 下载
  12. @Override
  13. public void marshal(Object arg0, HierarchicalStreamWriter writer,
  14. MarshallingContext arg2) {
  15. // TODO Auto-generated method stub
  16. Row map = (Row) arg0;
  17. for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
  18. Map.Entry entry = (Map.Entry) iterator.next();
  19. writer.addAttribute(entry.getKey().toString(), entry.getValue().toString());
  20. }
  21. }
  22. @Override
  23. public Object unmarshal(HierarchicalStreamReader reader,
  24. UnmarshallingContext context) {
  25. // TODO Auto-generated method stub
  26. Row map = new Row();
  27. populateMap(reader, context, map);
  28. return map;
  29. }
  30. protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Row map) {
  31. Iterator<String> iterator = reader.getAttributeNames();
  32. while (iterator.hasNext()) {
  33. Object key = iterator.next();
  34. String value = reader.getAttribute((String) key);
  35. map.put(key.toString(), value.toString());
  36. }
  37. }
  38. }

RowConverter是一个转换器类,作用是将每一个row结点转变一个HashMap。

测试类下载

Java代码  

  1. public class Xstream {
  2. private static String  xml;
  3. public static void main(String[] args) throws Exception{
  4. //初始化
  5. init();
  6. XStream xstream = new XStream(new XppDriver(new XmlFriendlyReplacer("_-", "_")));
  7. //解析xml文本
  8. xstream.processAnnotations(Results.class);
  9. Results results = (Results) xstream.fromXML(xml);
  10. //将解析出来的Results类对象转化成list列表
  11. List<Info> list = createList(Info.class,results);
  12. for(int i=0;i<list.size();i++){
  13. //打印
  14. Info info = list.get(i);
  15. System.out.println(info.toString());
  16. }
  17. }
  18. public static void init(){
  19. //初始化xml文本
  20. xml ="<results name=\"list\"><row pubtime=\"2016-04-13 16:40:13\" author=\"APP\"  id=\"140\" title=\"什么是公告\" content=\"公告,是公开宣告。\" /><row pubtime=\"2016-04-13 16:36:50\" author=\"网站\" id=\"138\" title=\"12345678\" content=\"12345678\"  /><row pubtime=\"2016-04-06 15:02:44\" author=\"网站\" id=\"134\" title=\"关于网站用户注册流程说明1\" content=\"关于用户注册流程说明\"  /><row pubtime=\"2016-03-30 18:32:13\" author=\"APP\"  id=\"126\" title=\"关于网站使用说明\" content=\"测试\"  /><row pubtime=\"2016-03-30 18:29:26\" author=\"网站\" id=\"125\" title=\"关于手机App使用说明\" content=\"123\"  /></results>";
  21. }
  22. public static <T> List createList(Class<T> clz ,Results results) throws Exception{
  23. List list = new ArrayList();
  24. for(Row row :results.getRows()){
  25. //根据class和Row生成对象放入list
  26. list.add(createObject(clz,row));
  27. }
  28. return list;
  29. }
  30. public static <T> T createObject(Class<T> clazz ,Row row) throws Exception{
  31. //初始化对象
  32. T obj = clazz.newInstance();
  33. //遍历Info类中所有方法
  34. for (Method method : clazz.getDeclaredMethods()) {
  35. String methodName = method.getName();
  36. Class[] perams = method.getParameterTypes();
  37. //找到set开头,长度大于3,并且入参数量为1的方法
  38. if (methodName.startsWith("set") && methodName.length() > 3 && perams.length == 1) {
  39. String temp = methodName.substring(3, methodName.length());
  40. //拿到属性名称
  41. String fieldName = temp.toLowerCase();
  42. //根据属性名称从HashMap中拿到对应的值
  43. String value = row.get(fieldName);
  44. if(value != null){
  45. //拿到该方法入参的Class,根据入参类型来决定调用方法形式
  46. Class  paramClass = perams[0];
  47. if (String.class.equals(paramClass)) {
  48. method.invoke(obj, value);
  49. } else if (Integer.class.equals(paramClass) || int.class.equals(paramClass)) {
  50. method.invoke(obj, Integer.valueOf(value));
  51. } else if (Long.class.equals(paramClass) || long.class.equals(paramClass)) {  下载
  52. method.invoke(obj, Long.valueOf(value));
  53. } else if (BigDecimal.class.equals(paramClass)) {
  54. method.invoke(obj, new BigDecimal(value));
  55. } else if (Boolean.class.equals(paramClass) || boolean.class.equals(paramClass)) {
  56. if(value.equals("true")||value.equals("TRUE"))
  57. method.invoke(obj, true);
  58. if(value.equals("false")||value.equals("FALSE"))
  59. method.invoke(obj, false);
  60. }
  61. }
  62. }
  63. }
  64. return obj;
  65. }
  66. }

最后是输出效果:

Java代码  

  1. Info [author=APP, content=公告,是公开宣告。, id=140, pubtime=2016-04-13 16:40:13, title=什么是公告]
  2. Info [author=网站, content=12345678, id=138, pubtime=2016-04-13 16:36:50, title=12345678]
  3. Info [author=网站, content=关于用户注册流程说明, id=134, pubtime=2016-04-06 15:02:44, title=关于网站用户注册流程说明1]
  4. Info [author=APP, content=测试, id=126, pubtime=2016-03-30 18:32:13, title=关于网站使用说明]
  5. Info [author=网站, content=123, id=125, pubtime=2016-03-30 18:29:26, title=关于手机App使用说明]
时间: 2024-08-06 20:07:39

XStream解析XML文本并用反射机制转换为对象的相关文章

java利用反射机制判断对象的属性是否为空

java利用反射机制判断对象的属性是否为空: Map<String,String> validateMap = new LinkedHashMap<String, String>(); validateMap.put("serial", "编号");validateMap.put("major", "专业"); public static <T> String validateFiledIs

XStream解析xml和json

XStream是一个在我看来比较好的一个第三方包了.因为它在解析时支持注解.这样很是方便,并且xml跟json这两种格式的文件都能进行解析,XStream本属于java的一个第三方包,甚是好用,若是拿它在android开发环境,也是能正常解析,但有点美中不足,因为android开发环境时,XStream不太支持json转对象,只支持对象转json,其他xml与对象的互转都支持.这样的话双解析就有了那么一点瑕疵之处,不过话说回来,没多少需求的数据交互会用json跟xml切来切去的,当只是json转

XStream解析xml格式的字符串的方法

ProcessStatusUploadRootList processStatusUploadRootList = null; try { XStream xStream = new XStream(); xStream.alias("Root", ProcessStatusUploadRootList.class); xStream.alias("Header", ProcessStatusUploadHeader.class); xStream.alias(&q

XStream解析XMl文件

1.新建RefundResult.java文件: /** * */ package com.saicfc.pmpf.resume.ccb.utils; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; /** * 解析银行返回数据 * @author lizhiyo

XStream解析XMl文件2

1.新建QueryOrders.java文件: /** * */ package com.saicfc.pmpf.resume.bocom.utils.resume; import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamImplicit; /** * @author lizhiyong

Xstream 解析xml文件内容

刚刚接手的一个项目,接到一个对接用户数据的需求,对方使用的是xml格式来传输文件,特此记下解析该类文件的方法 public interface XmlResolver<T> { XStream builder(); default T parse(String xml){ return (T) builder().fromXML(xml); } default T resolver(String xml){ return parse(xml); } } //测试类 public class T

java反射机制(一)—— 利用反射机制实例化对象

一.Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载.探知.使用编译期间完全未知的classes.换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体.或对其fields设值.或唤起其methods.(度娘文库是这么说的) 二.这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法.本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Cl

xstream解析xml

vo层: import java.util.List; import com.thoughtworks.xstream.annotations.XStreamAlias;import com.thoughtworks.xstream.annotations.XStreamImplicit;@XStreamAlias("result")public class BookResult { @XStreamImplicit(itemFieldName="item") pr

XStream解析xml代码

XStream xStream = new XStream(); xStream.processAnnotations(XmlBean.class); XmlBean fromXML = (XmlBean) xStream.fromXML(result); List<News> news = fromXML.newslist.news;