一、基本思路 【将xml文件对象转化为Map对象】先将xml文件转化为document对象,并获取到根节点,然后依次遍历二级节点
如果二级节点拥有子节点的话:进入递归
如果二级节点没有子节点的话:将数据封装在本层Map 中
如果二级节点部分拥有子节点,部分没有子节点,那么进行特殊处理。
二、具体代码
package xmlToPojo;
import java.io.File;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class xmlToCsdn {
@Test
public void main() {
String filepath = "F:/WH000413.xml";
Map map = mainMethod(filepath);
} public Map mainMethod(String filepath) {
Map map_finall = new LinkedHashMap();
try {
File file = new File(filepath);
// 读取xml文件,封装为doc对象
SAXReader saxreader = new SAXReader();
Document doc = saxreader.read(file);
Element rootElement = doc.getRootElement();
// 调用递归方法
map_finall.put(rootElement.getName(), DiGui(rootElement));
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map_finall;
} public Map DiGui(Element rootElement) {
// 对节点进行判断
int flag = hasGradeChrid(rootElement);
// 存储本层的map,采用LinkedHashMap,保证的顺序
Map map_this = new LinkedHashMap();
// 存储子节点的map,采用LinkedHashMap,保证的顺序
Map map_children = new LinkedHashMap();
// 获取节点迭代器
Iterator iterator = rootElement.elementIterator();
if (flag == 0) {// 说明该节点所有子节点均有子节点,进入递归
int num = 0;
while (iterator.hasNext()) {// 依次继续对节点进行操作
Element childelement = iterator.next();
map_children = DiGui(childelement);
map_this.put(childelement.getName() + "_" + num, map_children);
num++;
}
}
if (flag == 1) {// 说明该节点的所有子节点均无子节点,封装数据
while (iterator.hasNext()) {
Element childelement = iterator.next();
map_this.put(childelement.getName(),
(String) childelement.getData());
}
}
if (flag == 2) {// 说明了该节点的子节点有些拥有子节点,有些不拥有
int nodes = rootElement.elements().size();
// 获取子节点个数
while (nodes >= 1) {
nodes--;
int num = 0;
//为了让循环重复的节点,避免了key的冲突
Element element = iterator.next();
flag = hasGradeChrid(element);
//对节点进行判断
if (flag == 1) {//对于子节点,如果只是普通的子节点,那么直接将数进行封装
// 封装如map,String,String
map_this.put(element.getName(), element.getData());
}
else{//非普通子节点,那么进行递归
map_children = DiGui(element);
map_this.put(element.getName() + "_" + num, map_children);
//为了让循环重复的节点,避免了key的冲突
}
}
}
return map_this;
} /**
* 用于判断该节点的类型 0:说明该节点所有子节点均有子节点 1:说明该节点的所有子节点均无子节点 2:说明了该节点的子节点有些拥有子节点,有些不拥有
*
* @param rootelement
* @return
*/
public int hasGradeChrid(Element rootelement) {
int flag = 1;
// 初始为1,用与处理对没有子节点的节点进行判断
StringBuffer flag_arr = new StringBuffer();
Iterator iterator = rootelement.elementIterator();
while (iterator.hasNext()) {
Element element = iterator.next();
// 获取入参rootelement节点的子节点
// Iterator iterator_chirld = element.elementIterator();
if (element.elements().size() > 0) {// 判断是否有子节点
flag_arr.append("0");
} else {
flag_arr.append("1");
}
}
// 如果只包含0,说明该节点所有子节点均有子节点
if (flag_arr.toString().contains("0")) {
flag = 0;
}
// 如果只包含1,说明该节点的所有子节点均无子节点
if (flag_arr.toString().contains("1")) {
flag = 1;
}
// 如果同时包含了,0,1,说明了该节点的子节点有些拥有子节点,有些不拥有
if (flag_arr.toString().contains("0")
&& flag_arr.toString().contains("1")) {
flag = 2;
}
return flag;
}
}
三、测试例子
四、结果
{WH000413={Head_0={SendTime=20180822112506, FunctionCode=4346, SignerInfo=45, Version=1.0}, Declaration_1={ReturnHead_0={ApplyID=5C8610D, No=20180727155013, ProType=1, ProID=de, ProName=eee, ProINFO=发送成功}, ReturnDetail_1={ListInfo_0={USD=122.0545, Sum=29.7694, Currency=JJJ, Infos_0={Info_0={Qty=0, Unit=Unit1, UnPrice=0.5989}, Info_1={Qty=0, Unit=Unit2, UnPrice=0.2030}}}}}}}
五、小结 其实逻辑也比较简单,只是有时要根据xml报文的情况进行适当的修改。不过也基本离不开"本层数据本层封装,若有子节点往下钻"的基本思路。
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)