在日常的开发当中,经常遇到xml类型数据的解析,在解析的过程当中需要将xml中的数据映射成java实体对象,如果只是简单的几个字段,我们使用平常的set即可,但是经常的遇到字段过多的情况,set起来就很痛苦,如果能和java的反射配合灵活使用,事情会变的简单许多。
XML示例
这里使用最简单的xml做示例,复杂的嵌套循环同样适用。
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Copyright w3school.com.cn -->
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
<num>123</num>
</note>
java实体类
使用的不同类型int,反射时针对Stirng以外的类型需要判断处理下。
public class Note {
private String from;
private String to;
private String heading;
private String body;
private int num;
...省略 get set 方法
@Override
public String toString() {
return "Note{" +
"from='" + from + '\'' +
", to='" + to + '\'' +
", heading='" + heading + '\'' +
", body='" + body + '\'' +
", num=" + num +
'}';
}
}
XML解析
使用dom4j进行xml数据解析,其他工具类同理,少不了循环判断获取,灵活变通。
public static void main(String[] args) {
//使用dom4j进行xml解析
try {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read("./note.xml");
Element rootElement = doc.getRootElement();
List<Element> elements = rootElement.elements();
Note note = new Note();
Class<? extends Note> aClass = note.getClass();
Field[] declaredFields = aClass.getDeclaredFields();
for (Element element : elements) {
String name = element.getName();
Object data = element.getData();
//使用java反射设置属性
for (Field declaredField : declaredFields) {
if (declaredField.getName().equals(name)) {
declaredField.setAccessible(true);
String type = declaredField.getType().getName();
//针对不同类型做处理
if (type.equals("int")) {
Integer intData = Integer.valueOf(data.toString());
declaredField.set(note, intData);
} else {
declaredField.set(note, data);
}
}
}
}
System.out.println(note);
} catch (Exception e) {
e.printStackTrace();
}
}
输出
Note{from='John', to='George', heading='Reminder', body='Don't forget the meeting!', num=123}
总结
示例的中xml属性较少,但是如果多增一些,解析代码几乎不用改动,不变的痛苦是java中的属性需要挨个去写。