使用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文件,结果如下:
自此说明已解析成功。