使用JAXB解析XML文件


placeholder image
admin 发布于:2022-07-04 22:04:30
阅读:loading

1.基本介绍

这几年由于工作中的许多接口交互都使用到了XML来传递报文数据,本篇文章特对XML数据的解析以我熟悉的方式分享给大家。在十多年前Spring没有这么普及的时候(或者说我还是非常水的水军的时候),关于XML文件的解析还是一道标准的面试题,大概问到的则是解析XML的组件有几种,并且这几种解析的区别,同时我们还经常引以为傲的使用XML来自定义参数配置文件,再配合dom4j之类的解析组件进行参数解析,最终将XML中的标签以及熟悉映射到我们的Javabean数据对下中。巧的是曾经分享过一次会议是JDK的新特性,当我整理到JDK6的新特性时发现了新增强的JAXB特性,仔细了解后发现其是Java官方提供的读取和生成XML文档的实现,大家可以在官网的介绍中查看更多更精准的描述与细节知识点,参考官网地址为:https://www.oracle.com/technical-resources/articles/javase/jaxb.html,如下图的优势是从官网的英文翻译出的图片,如下

image.png

将XML数据转换为Java对象是解析数据的最终结果,也有见过将XML转换为JSON对象,再去解析JSON数据的,但我个人还是觉得使用JAXB作为XML解析介质最为妥当,使用它的前提条件则是需要一个完整的XML结构,最好是构造出高度兼容各种场景的全节点或全属性的文档结构,比如某个节点的子节点是多个子节点,则最好给出多个子节点的原始XML数据,使得XML结构的子层属于数组类的。本文介绍使用IDEA将XML转换为XSD(也可以转换为DTD,但个人未使用过),再将XSD转换为Java对象的实现,最终提供JAXB的代码工具类实现XML与Java对象的互相转换,参考具体实现如下。

2.示例XML文件

以示例项目中的pom.xml文件为例,作为原始xml数据。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>examples</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.weblookandfeel</groupId>
            <artifactId>weblaf-ui</artifactId>
            <version>1.2.13</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.7</version>
        </dependency>
    </dependencies>


</project>

3.转换为XSD

将pom.xml转换未xsd文件,使用IDEA自带的功能菜单将xml转换为xsd,选中xml文件鼠标右键(或者打开文件在内容区域右键)点击“Generate XSD Schema from XML File...”,再弹出的新窗口设置各种参数设置后,生成XSD文件,再在XSD文件的基础上生成对象的Java代码文件,参考如下步骤所示:

image.png

(选择生成XSD功能)

image.png

(生成XSD文件)

image.png

(根据XSD生成Java代码)

image.png

(设置项目代码中的包路径和取消标记文件的只读参数)

image.png

(生成Java代码文件)

【注意】

有些时候在使用xsd生成Java代码时,创建的Java文件需要转码,因为生成出来的源代码并不是UTF-8编码,需要使用NotePad++进行转码,在菜单栏--转换为 UTF-8编码即可。因为默认生成的文件是ANSI编码,若使用记事本软件另存为UTF-8时,转换后的UTF-8带有BOM,所以还需要再次转换。

4.XML与Java工具类

package cn.chendd.example;

import ...;

/**
 * Xml转换工具类
 *
 * @author chendd
 * @date 2022/7/5 9:20
 */
public final class XmlConvert {

    /**
     * 将对象转换为xml
     * @param bean 对象
     * @param charset 编码
     * @param schemaLocation schemaLocation
     * @param <T> 泛型
     * @return xml
     */
    public static <T> String convertBean2Xml(T bean , String charset , String schemaLocation) {
        String value;
        try (StringWriter writer = new StringWriter()){
            JAXBContext context = JAXBContext.newInstance(bean.getClass());
            Marshaller marshaller = context.createMarshaller();
            //设置编码
            if (StringUtils.isNotEmpty(charset)) {
                marshaller.setProperty(Marshaller.JAXB_ENCODING , charset);
            }
            //设置schema路径
            if (StringUtils.isNotEmpty(schemaLocation)) {
                marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION , schemaLocation);
            }
            //是否格式化xml
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT , true);
            //是否去除xml头文件
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT , false);
            marshaller.marshal(bean , writer);
            value = writer.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return value;
    }

    /**
     * 将对象转换为xml
     * @param bean 对象
     * @param <T> 泛型
     * @return xml
     */
    public static <T> String convertBean2Xml(T bean) {
        return convertBean2Xml(bean , StandardCharsets.UTF_8.name() , null);
    }

    /**
     * 将xml文本转换为bean对象
     * @param xml xml
     * @param clazz beanClass
     * @param <T> 泛型
     * @return bean对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T convertXml2Bean(String xml , Class<T> clazz) {
        JAXBContext context;
        try {
            context = JAXBContext.newInstance(clazz);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            return (T) unmarshaller.unmarshal(new StringReader(xml));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

5.生成XML代码参考

package cn.chendd.example;

import ...;

/**
 * 创建Xml
 *
 * @author chendd
 * @date 2022/7/5 9:11
 */
public class XmlWrite {

    public static Project createProject() {
        ObjectFactory factory = new ObjectFactory();
        //构造跟节点<project>
        Project project = factory.createProject();
        //构造<modelVersion>
        project.setModelVersion(factory.createModelVersion("4.0.0").getValue());
        //构造<groupId>
        project.setGroupId(factory.createGroupId("org.example").getValue());
        //构造<version>
        project.setVersion(factory.createVersion("1.0.0").getValue());
        //构造<properties>
        Properties properties = factory.createProperties();
        properties.setMavenCompilerSource("8");
        properties.setMavenCompilerTarget("8");
        project.setProperties(properties);
        //构造<dependencies>
        Dependencies dependencies = factory.createDependencies();
        project.setDependencies(dependencies);
        Dependency weblaf = new Dependency();
        weblaf.setGroupId("com.weblookandfeel");
        weblaf.setArtifactId("weblaf-ui");
        weblaf.setVersion("1.2.13");
        Dependency lang3 = new Dependency();
        lang3.setGroupId("org.apache.commons");
        lang3.setArtifactId("commons-lang3");
        lang3.setVersion("3.9");
        Dependency io = new Dependency();
        io.setGroupId("org.apache.commons");
        io.setArtifactId("commons-lang3");
        io.setVersion("3.9");
        List<Dependency> dependencyList = dependencies.getDependency();
        dependencyList.add(weblaf);
        dependencyList.add(lang3);
        dependencyList.add(io);
        return project;
    }

}

6.源码下载

demo比较简单,IDEA工程源码下载examples.zip

 点赞


 发表评论

当前回复:作者

 评论列表


留言区