一、简介
最近在项目中需要用到XML解析成实体类,并将值封装到实体类属性中,于是封装了一个工具类。下面是具体的代码:
NHXmlParseUtils.java:
package com.ly.cloud.common.webservice;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.*;
/**
* @description: XML解析统一工具类
* @author: weishihuai
* @mail: weishihuai@ly-sky.com
* @Date: 2020/6/28 14:39
* @version: 1.0
*/
public class NHXmlParseUtils {
private static final Logger logger = LoggerFactory.getLogger(NHXmlParseUtils.class);
/**
* 解析XML文本映射到实体类
*
* @param returnXml 待解析的XML文本
* @param cls 解析生成后映射的Class类对象
* @param fieldXmlPaths XMLPaths集合(XML中的标签路径)
* @return
*/
public static List<?> parserXmlToEntity(String returnXml, Class cls, Map<String, String> fieldXmlPaths) {
Document document;
try {
//将给定文本解析为XML文档并返回新创建的文档
document = DocumentHelper.parseText(returnXml);
//存储属性的名称
List<String> filedNames = new ArrayList<>();
//存放<属性,values>
Map<String, List<Node>> map = new HashMap<>();
if (null != fieldXmlPaths && !fieldXmlPaths.isEmpty()) {
Iterator iterator = fieldXmlPaths.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry) iterator.next();
Object key = entry.getKey();
Object value = entry.getValue();
List<Node> nodes = document.selectNodes(value.toString());
List<Node> list = new ArrayList<>();
for (Node node : nodes) {
list.add(node);
}
//循环放入属性-> 对应的节点
map.put(key.toString(), list);
filedNames.add(key.toString());
}
}
List list = new ArrayList();
//循环将节点的值放入到对象中,然后放入到list
for (int i = 0; i < map.get(filedNames.get(0)).size(); i++) {
Object instance = cls.newInstance();
for (String fieldName : filedNames) {
//拼接方法名称
String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
//通过反射获取setter方法
Method method = cls.getMethod(methodName, String.class);
//通过invoke调用实体类对应的setter方法
method.invoke(instance, map.get(fieldName).get(i).getText());
}
list.add(instance);
}
return list;
} catch (Exception e) {
logger.error("XML解析失败!");
e.printStackTrace();
}
return null;
}
}
测试:
package com.ly.cloud.common.webservice;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
String returnXml = "<RdrLoanInfo><Cardno>1607300009</Cardno><Name>李明杰</Name><Title>射雕英雄传</Title><Callno>I247.58/204</Callno><Barcode>A2144907</Barcode><Local>书库(304室)</Local><Author>金庸著</Author><Loandate>20200102</Loandate><Returndate>*20200911</Returndate><Cardno>1607300009</Cardno><Name>李明杰</Name><Title>射雕英雄传</Title><Callno>I247.58/204</Callno><Barcode>A2144904</Barcode><Local>书库(304室)</Local><Author>金庸著</Author><Loandate>20200102</Loandate><Returndate>*20200911</Returndate></RdrLoanInfo>";
//解析返回的XML数据
Map<String, String> fieldXmlPaths = new HashMap<>();
fieldXmlPaths.put("Title", "//RdrLoanInfo/Title");
fieldXmlPaths.put("Callno", "//RdrLoanInfo/Callno");
fieldXmlPaths.put("Barcode", "//RdrLoanInfo/Barcode");
fieldXmlPaths.put("Local", "//RdrLoanInfo/Local");
fieldXmlPaths.put("Author", "//RdrLoanInfo/Author");
fieldXmlPaths.put("Loandate", "//RdrLoanInfo/Loandate");
fieldXmlPaths.put("Returndate", "//RdrLoanInfo/Returndate");
List<ReturnBook> studentBooksList = (List<ReturnBook>) NHXmlParseUtils.parserXmlToEntity(returnXml, ReturnBook.class, fieldXmlPaths);
System.out.println(studentBooksList);
}
}
/**
* 借书信息类
*/
class ReturnBook {
private String Title;
private String Callno;
private String Barcode;
private String Local;
private String Author;
private String Loandate;
private String Returndate;
public String getTitle() {
return Title;
}
public void setTitle(String title) {
Title = title;
}
public String getCallno() {
return Callno;
}
public void setCallno(String callno) {
Callno = callno;
}
public String getBarcode() {
return Barcode;
}
public void setBarcode(String barcode) {
Barcode = barcode;
}
public String getLocal() {
return Local;
}
public void setLocal(String local) {
Local = local;
}
public String getAuthor() {
return Author;
}
public void setAuthor(String author) {
Author = author;
}
public String getLoandate() {
return Loandate;
}
public void setLoandate(String loandate) {
Loandate = loandate;
}
public String getReturndate() {
return Returndate;
}
public void setReturndate(String returndate) {
Returndate = returndate;
}
@Override
public String toString() {
return "ReturnBook{" +
"Title='" + Title + '\'' +
", Callno='" + Callno + '\'' +
", Barcode='" + Barcode + '\'' +
", Local='" + Local + '\'' +
", Author='" + Author + '\'' +
", Loandate='" + Loandate + '\'' +
", Returndate='" + Returndate + '\'' +
'}';
}
}
运行结果:
[ReturnBook{Title='射雕英雄传', Callno='I247.58/204', Barcode='A2144907', Local='书库(304室)', Author='金庸著', Loandate='20200102', Returndate='*20200911'}, ReturnBook{Title='射雕英雄传', Callno='I247.58/204', Barcode='A2144904', Local='书库(304室)', Author='金庸著', Loandate='20200102', Returndate='*20200911'}]
当然,如果不需要封装到实体类中,也可以稍微改善一下,封装到Map中也是可以的。