使用JAXB解析XML文件
admin 发布于:2022-07-04 22:04:30
阅读:loading
这几年由于工作中的许多接口交互都使用到了XML来传递报文数据,本篇文章特对XML数据的解析以我熟悉的方式分享给大家。在十多年前Spring没有这么普及的时候(或者说我还是非常水的水军的时候),关于XML文件的解析还是一道标准的面试题,大概问到的则是解析XML的组件有几种,并且这几种解析的区别,同时我们还经常引以为傲的使用XML来自定义参数配置文件,再配合dom4j之类的解析组件进行参数解析,最终将XML中的标签以及熟悉映射到我们的Javabean数据对下中。巧的是曾经分享过一次会议是JDK的新特性,当我整理到JDK6的新特性时发现了新增强的JAXB特性,仔细了解后发现其是Java官方提供的读取和生成XML文档的实现,大家可以在官网的介绍中查看更多更精准的描述与细节知识点,参考官网地址为:https://www.oracle.com/technical-resources/articles/javase/jaxb.html,如下图的优势是从官网的英文翻译出的图片,如下
将XML数据转换为Java对象是解析数据的最终结果,也有见过将XML转换为JSON对象,再去解析JSON数据的,但我个人还是觉得使用JAXB作为XML解析介质最为妥当,使用它的前提条件则是需要一个完整的XML结构,最好是构造出高度兼容各种场景的全节点或全属性的文档结构,比如某个节点的子节点是多个子节点,则最好给出多个子节点的原始XML数据,使得XML结构的子层属于数组类的。本文介绍使用IDEA将XML转换为XSD(也可以转换为DTD,但个人未使用过),再将XSD转换为Java对象的实现,最终提供JAXB的代码工具类实现XML与Java对象的互相转换,参考具体实现如下。
以示例项目中的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>
将pom.xml转换未xsd文件,使用IDEA自带的功能菜单将xml转换为xsd,选中xml文件鼠标右键(或者打开文件在内容区域右键)点击“Generate XSD Schema from XML File...”,再弹出的新窗口设置各种参数设置后,生成XSD文件,再在XSD文件的基础上生成对象的Java代码文件,参考如下步骤所示:
(选择生成XSD功能)
(生成XSD文件)
(根据XSD生成Java代码)
(设置项目代码中的包路径和取消标记文件的只读参数)
(生成Java代码文件)
【注意】
有些时候在使用xsd生成Java代码时,创建的Java文件需要转码,因为生成出来的源代码并不是UTF-8编码,需要使用NotePad++进行转码,在菜单栏--转换为 UTF-8编码即可。因为默认生成的文件是ANSI编码,若使用记事本软件另存为UTF-8时,转换后的UTF-8带有BOM,所以还需要再次转换。
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);
}
}
}
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;
}
}
demo比较简单,IDEA工程源码下载examples.zip
点赞