使用SpringBoot环境解析固定格式的xml,步骤如下:

1)使用SAXReader读取文件,故导入需要的依赖



<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
</dependency>


2)编辑要解析的xml文件



<?xml version="1.0" encoding="utf-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Schema-3.0.xsd"
License="00120-100290-002">
<Event>
<School name="武汉大学" establishmentDate="1997-12-20">
<Class clazz="计算机101">
<Student name="张三" age="20" sex="男"></Student>
<Student name="李敏" age="15" sex="女"></Student>
<Student name="赵柳" age="21" sex="女"></Student>
<Student name="李民" age="21" sex="男"></Student>
</Class>
<Class clazz="计算机102">
<Student name="赵虹" age="22" sex="男"></Student>
<Student name="钟菲菲" age="19" sex="女"></Student>
<Student name="汪敏" age="20" sex="女"></Student>
<Student name="杨倩" age="18" sex="女"></Student>
</Class>
</School>
<School name="清华大学" establishmentDate="1988-10-03">
<Class clazz="计算机211">
<Student name="赵飞" age="20" sex="男"></Student>
<Student name="李慧" age="15" sex="女"></Student>
</Class>
<Class clazz="软件311">
<Student name="赵宏宇" age="22" sex="男"></Student>
<Student name="汪敏敏" age="21" sex="女"></Student>
<Student name="杨明明" age="18" sex="男"></Student>
</Class>
</School>
</Event>
</Document>


3)编写文件工具类FileUtil,用于将MultipartFile转为File



package com.zys.demo.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
public class FileUtil {

private static final String TEMP_PATH = "D://temp";

/**
* MultipartFile 转 File
*
* @param file
* @throws Exception
*/
public static File multipartFileToFile(MultipartFile file) throws Exception {
File toFile = null;
if (!file.equals("") && file.getSize() > 0) {
InputStream ins = file.getInputStream();
File tempFile = new File(TEMP_PATH);
if (!(tempFile.exists() && tempFile.isDirectory())) {
tempFile.mkdirs();
}
toFile = new File(tempFile + File.separator + file.getOriginalFilename());
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}

//获取流文件
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}

//删除转换存储的临时文件
public static void deleteMultipartFile(MultipartFile file) {
File tempFile = new File(TEMP_PATH + File.separator + file.getOriginalFilename());
tempFile.delete();
}

}


在进行类型转换时,会生成一个临时文件,默认存在项目根目录下。这里指定了目录,也可在配置文件配置,然后给文件工具类添加@Component注解,使用@Value注解获取配置的临时路径。在读取完数据后需要将此文件删除。

4)创建解析存储的对象:

SchoolModel:学校对象



package com.zys.demo.entity.model;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;

@Data
@Accessors(chain = true)
public class SchoolModel {

private String name;

private String establishmentDate;

private List<ClazzModel> clazzModelList;
}


ClazzModel:班级对象



package com.zys.demo.entity.model;

import lombok.Data;
import lombok.experimental.Accessors;

import java.util.List;

@Data
@Accessors(chain = true)
public class ClazzModel {

private String clazz;

private List<StudentModel> studentModelList;
}


StudentModel:学生对象



package com.zys.demo.entity.model;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class StudentModel {

private String name;

private String sex;

private Integer age;

}


5)编写xml解析的工具类ParseXmlUtil



package com.zys.demo.util;


import com.zys.demo.entity.model.ClazzModel;
import com.zys.demo.entity.model.StudentModel;
import com.zys.demo.entity.model.SchoolModel;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
* xml文件解析
*/
@Slf4j
public class ParseXmlUtil {

private static ParseXmlUtil parseXmlUtil = null;

public static ParseXmlUtil getInstance() {
if (null == parseXmlUtil) {
parseXmlUtil = new ParseXmlUtil();
}
return parseXmlUtil;
}


private List<SchoolModel> schoolModelList;
private List<ClazzModel> clazzModelList;
private List<StudentModel> studentModelList;

/**
* 解析xml
*
* @param file
* @return
*/
public List<SchoolModel> parse(File file) {
// 创建一个SAXReader对象
SAXReader sax = new SAXReader();
// 获取document对象,如果文档无节点,则会抛出Exception提前结束
Document document;
try {
schoolModelList = new ArrayList<>();
clazzModelList = new ArrayList<>();
studentModelList = new ArrayList<>();
document = sax.read(file);
Element root = document.getRootElement().element("Event");
List<Element> elements = root.elements();
elements.stream().forEach(node -> getNodes(node));
} catch (DocumentException e) {
e.printStackTrace();
log.error("xml读取异常,原因:文档无节点");
}
return schoolModelList;
}

/**
* 递归遍历所有子节点
*/
private void getNodes(Element node) {
String nodeName = node.getName();
if (nodeName.equals("School")) {
SchoolModel school = new SchoolModel();
school.setName(node.attributeValue("name"));
school.setEstablishmentDate(node.attributeValue("establishmentDate"));
//获取下级节点
List<Element> elementList = node.elements();
elementList.stream().forEach(item -> {
this.getNodes(item);
});
school.setClazzModelList(clazzModelList);
schoolModelList.add(school);
//重置列表
clazzModelList = new ArrayList<>();
} else if (nodeName.equals("Class")) {
ClazzModel clazz = new ClazzModel();
clazz.setClazz(node.attributeValue("clazz"));
//获取下级节点
List<Element> elementList = node.elements();
elementList.stream().forEach(item -> {
this.getNodes(item);
});
clazz.setStudentModelList(studentModelList);
clazzModelList.add(clazz);
//重置列表
studentModelList = new ArrayList<>();
} else if (nodeName.equals("Student")) {
StudentModel student = new StudentModel();
student.setName(node.attributeValue("name"));
student.setAge(Integer.parseInt(node.attributeValue("age")));
student.setSex(node.attributeValue("sex"));
studentModelList.add(student);
}
}


}


6)编写上传的接口



package com.zys.demo.controller;

import com.zys.demo.entity.model.SchoolModel;
import com.zys.demo.util.FileUtil;
import com.zys.demo.util.ParseXmlUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.List;

@RestController
@RequestMapping("/file")
public class FileController {

@PostMapping("/import")
public List<SchoolModel> importXml(MultipartFile file) throws Exception {
//文件转换
File fileToFile = FileUtil.multipartFileToFile(file);
//读取内容
List<SchoolModel> modelList = ParseXmlUtil.getInstance().parse(fileToFile);
//删除临时文件
FileUtil.deleteMultipartFile(file);
return modelList;
}
}


7)在static下创建上传的页面test.html



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>xml解析</title>
</head>
<body>
<form action="/file/import" method="post" enctype="multipart/form-data">
<input type="file" name="file" value="选择文件">
<input type="submit" value="上传">
</form>
</body>
</html>


8)启动项目,上传此xml文件,结果如下:

Java解析xml文件_spring

 自此说明已解析成功。