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

2024-06-03 11:58

本文主要是介绍XStream解析XML文本并用反射机制转换为对象,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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

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

public class Info {private String id;
private String title;
private String content;
private String author;
private String pubtime;
public String getId {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPubtime {
return pubtime;
}
public void setPubtime(String pubtime) {
this.pubtime = pubtime;
}
@Override
public String toString {
return "Info [author=" + author + ", content=" + content + ", id=" + id
+ ", pubtime=" + pubtime + ", title=" + title + "]";
}}
@XStreamConverter(RowConverter.class)
public class Row extends HashMap<String, String> {private static final long serialVersionUID = 5619951409573339302L;
}
@XStreamAlias("results")
public class Results {
@XStreamAlias("name")@XStreamAsAttributeprivate String name;@XStreamImplicit(itemFieldName = "row")private List<Row> rows;public String getName {return name;}public void setName(String name) {this.name = name;}public List<Row> getRows {
return rows;
}public void setRows(List<Row> rows) {
this.rows = rows;
}}
public class RowConverter extends AbstractCollectionConverter {public RowConverter(Mapper mapper) {
super(mapper);
// TODO Auto-generated constructor stub
}@Override
public boolean canConvert(Class arg0) {
// TODO Auto-generated method stub
return Row.class.equals(arg0);
}@Override
public void marshal(Object arg0, HierarchicalStreamWriter writer,
MarshallingContext arg2) {
// TODO Auto-generated method stub
Row map = (Row) arg0;for (Iterator iterator = map.entrySet.iterator; iterator.hasNext;) {Map.Entry entry = (Map.Entry) iterator.next;writer.addAttribute(entry.getKey.toString, entry.getValue.toString);}
}@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
// TODO Auto-generated method stubRow map = new Row;populateMap(reader, context, map);return map;
}protected void populateMap(HierarchicalStreamReader reader, UnmarshallingContext context, Row map) {Iterator<String> iterator = reader.getAttributeNames;while (iterator.hasNext) {Object key = iterator.next;String value = reader.getAttribute((String) key);map.put(key.toString, value.toString);}}
}

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

测试类:

publicclass Xstream {private static String  xml;public static void main(String[] args) throws Exception{
//初始化
init;XStream xstream = new XStream(new XppDriver(new 
XmlFriendlyReplacer("_-", "_")));
//解析xml文本
xstream.processAnnotations(Results.class);
Results results = (Results) xstream.fromXML(xml);
//将解析出来的Results类对象转化成list列表
List<Info> list = createList(Info.class,results);for(int i=0;i<list.size;i++){
//打印
Info info = list.get(i);
System.out.println(info.toString);
}}
public static void init{
//初始化xml文本
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>";
}
public static <T> List createList(Class<T> clz ,Results 
results) throws Exception{
List list = new ArrayList;
for(Row row :results.getRows){
//根据class和Row生成对象放入list
list.add(createObject(clz,row));}
return list;
}
public static <T> T createObject(Class<T> clazz ,Row row) 
throws Exception{
//初始化对象
T obj = clazz.newInstance;
//遍历Info类中所有方法
for (Method method : clazz.getDeclaredMethods) {
String methodName = method.getName;
Class perams = method.getParameterTypes;
//找到set开头,长度大于3,并且入参数量为1的方法
if (methodName.startsWith("set") && methodName.length > 3 
&& perams.length == 1) {String temp = methodName.substring(3, methodName.length);
//拿到属性名称
String fieldName = temp.toLowerCase;
//根据属性名称从HashMap中拿到对应的值
String value = row.get(fieldName);if(value != null){
//拿到该方法入参的Class,根据入参类型来决定调用方法形式
Class  paramClass = perams[0];
if (String.class.equals(paramClass)) {
method.invoke(obj, value);
} else if (Integer.class.equals(paramClass) || 
int.class.equals(paramClass)) {
method.invoke(obj, Integer.valueOf(value));
} else if (Long.class.equals(paramClass) || 
long.class.equals(paramClass)) {
method.invoke(obj, Long.valueOf(value));
} else if (BigDecimal.class.equals(paramClass)) {
method.invoke(obj, new BigDecimal(value));
} else if (Boolean.class.equals(paramClass) || 
boolean.class.equals(paramClass)) {
if(value.equals("true")||value.equals("TRUE"))
method.invoke(obj, true);
if(value.equals("false")||value.equals("FALSE"))
method.invoke(obj, false);
}
}}
}
return obj;
}
}

最后是输出效果:

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

这篇关于XStream解析XML文本并用反射机制转换为对象的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1026923

相关文章

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

在C#中合并和解析相对路径方式

《在C#中合并和解析相对路径方式》Path类提供了几个用于操作文件路径的静态方法,其中包括Combine方法和GetFullPath方法,Combine方法将两个路径合并在一起,但不会解析包含相对元素... 目录C#合并和解析相对路径System.IO.Path类幸运的是总结C#合并和解析相对路径对于 C

Spring使用@Retryable实现自动重试机制

《Spring使用@Retryable实现自动重试机制》在微服务架构中,服务之间的调用可能会因为一些暂时性的错误而失败,例如网络波动、数据库连接超时或第三方服务不可用等,在本文中,我们将介绍如何在Sp... 目录引言1. 什么是 @Retryable?2. 如何在 Spring 中使用 @Retryable

java中VO PO DTO POJO BO DO对象的应用场景及使用方式

《java中VOPODTOPOJOBODO对象的应用场景及使用方式》文章介绍了Java开发中常用的几种对象类型及其应用场景,包括VO、PO、DTO、POJO、BO和DO等,并通过示例说明了它... 目录Java中VO PO DTO POJO BO DO对象的应用VO (View Object) - 视图对象

Java解析JSON的六种方案

《Java解析JSON的六种方案》这篇文章介绍了6种JSON解析方案,包括Jackson、Gson、FastJSON、JsonPath、、手动解析,分别阐述了它们的功能特点、代码示例、高级功能、优缺点... 目录前言1. 使用 Jackson:业界标配功能特点代码示例高级功能优缺点2. 使用 Gson:轻量

Java如何接收并解析HL7协议数据

《Java如何接收并解析HL7协议数据》文章主要介绍了HL7协议及其在医疗行业中的应用,详细描述了如何配置环境、接收和解析数据,以及与前端进行交互的实现方法,文章还分享了使用7Edit工具进行调试的经... 目录一、前言二、正文1、环境配置2、数据接收:HL7Monitor3、数据解析:HL7Busines

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

Java将时间戳转换为Date对象的方法小结

《Java将时间戳转换为Date对象的方法小结》在Java编程中,处理日期和时间是一个常见需求,特别是在处理网络通信或者数据库操作时,本文主要为大家整理了Java中将时间戳转换为Date对象的方法... 目录1. 理解时间戳2. Date 类的构造函数3. 转换示例4. 处理可能的异常5. 考虑时区问题6.

Java操作xls替换文本或图片的功能实现

《Java操作xls替换文本或图片的功能实现》这篇文章主要给大家介绍了关于Java操作xls替换文本或图片功能实现的相关资料,文中通过示例代码讲解了文件上传、文件处理和Excel文件生成,需要的朋友可... 目录准备xls模板文件:template.xls准备需要替换的图片和数据功能实现包声明与导入类声明与

C#反射编程之GetConstructor()方法解读

《C#反射编程之GetConstructor()方法解读》C#中Type类的GetConstructor()方法用于获取指定类型的构造函数,该方法有多个重载版本,可以根据不同的参数获取不同特性的构造函... 目录C# GetConstructor()方法有4个重载以GetConstructor(Type[]