1. 关于XStream的官网介绍。
2. 假设我们有如下结构的XSD,那么,当我们想要解析这种结构的XML文件取得数据的话,就可以使用XStream了。
这个查看XSD结构的工具是:Altova XMLSpy。
使用这个工具之前,我们需要先生成好图片里所有节点的XmlBean,而且每个XmlBean都有嵌套、集合的关系,这些概念可以参考:XStream简介。
3. pom.xml加入依赖。
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
4. 假设我们最顶层的XmlBean名为XmlRoot.class。
package com.bas.utils;
import com.thoughtworks.xstream.XStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class XStreamUtils {
public static Object xmlToBean(InputStream inputStream, Class clazz) throws IOException {
XStream xStream = new XStream();
XStream.setupDefaultSecurity(xStream);
Class[] clazzes = new Class[]{ clazz };
xStream.autodetectAnnotations(true);
xStream.processAnnotations(clazz);
//FileReader fileReader = new FileReader("D:\\test\\20200108.xml");
//InputStream inputStream = new FileInputStream(new File("D:\\test\\20200108.xml"));
xStream.ignoreUnknownElements();
xStream.allowTypes(clazzes);
//xStream.registerConverter(new StringToDateConverter());
try {
return xStream.fromXML(inputStream);
}catch (Exception e) {
inputStream.close();
return null;
}
}
}
public static void main(String[] args) throws FileNotFoundException {
InputStream inputStream = new FileInputStream(new File("D:\\test\\20200108.xml"));
XStreamUtils.xmlToBean(inputStream, XmlRoot.class);
}
5. 一般来说,我们都会遇到时间格式不统一的情况,那么我们可以添加一个时间转换器。
package com.bas.converter;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class StringToDateConverter implements Converter {
/**
* 用来判断需要序列化的对象是否使用此转换器,用户可以在此方法自定义使用的类,
* 或者可以直接返回true来表名此转换器为通用。
* xstream会自动执行此方法,如果canConvert()的返回结果为false,转换器将不起作用。
*/
@Override
public boolean canConvert(Class arg0) {
// TODO Auto-generated method stub
return arg0.equals(Date.class);
}
/**
* 对于java对象转换成xml文件的自定义序列化操作将会执行此方法。
* 方法含有三个参数,分别是:需要转换的对象、序列化输出对象和序列化上下文对象
*/
@Override
public void marshal(Object arg0, HierarchicalStreamWriter arg1,
MarshallingContext arg2) {
// TODO Auto-generated method stub
}
/**
* 对于xml文件转换成java对象是需要执行的方法。方法含有两个参数,分别是:反序列化读取对象和反序列化上下文对象
*/
@Override
public Object unmarshal(HierarchicalStreamReader arg0,
UnmarshallingContext arg1) {
// TODO Auto-generated method stub
String value = arg0.getValue();
if (value == null || value.trim().length() == 0) {
return null;
}
//String value = "2012-10-01T11:09:00.000Z";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Date date = null;
try {
date = sdf.parse(value);
} catch (ParseException e) {
e.printStackTrace();
}
return date;
}
}
然后在XStreamUtils执行xStream.registerConverter(new StringToDateConverter());注册就可以了。
6. 特别地,当配置XmlBean遇到节点既有属性又有内容的时候,可以这样配置。
<node attribute="value">text</node>
@XStreamAlias("node")
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"text"})
public class Node {
private String attribute;
private String text; // node节点的内容
}
附:
1. 开源dom框架xStream转换器(Converter)的基本用法
2. 如果需要通过xsd文件生成一个xml文件来测试,可以通过eclipse生成,详细的可以参考:How to Generate XML from XSD in Eclipse