• 周五. 8月 19th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Java解析xml文件

admin

11月 28, 2021

使用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文件,结果如下:

 自此说明已解析成功。

就是这么简单,你学废了吗?感觉有用的话,给笔者点个赞吧 !

发表回复

您的电子邮箱地址不会被公开。