本文适用范围期望通过每一次分享,让技术的门槛变低,落地更容易。 —— 周围
- 实际工作中遇到关于解析和转换xml的问题
- 不懂,想详细了解学习如何解析xml的同学
通过本文,你将解决如下问题:
- xml数据结构对应的java实体结构是如何绑定的
- 如何将xml结构数据转换成对象
- 如何将对象转换为xml
|
E37AA69997D0F399E040007F0100484D 20130809103931E37AA70270E78822E040007F01004851@gd.zg FR20130809103441000000001054@90001113@gd.zg 40001009@jm.gd.cp 中共江门市委办秘书科 1 RC01 2013-08-09 10:39:32 2013-08-09 10:35:21 201308071@jm.gd.cp 江门市委办法规文件报备系统 E201310290563707@20000007@jm.gd.cp-print 21800168@jm.gd.cp 测试用户2 2013-10-30 9:19:55
上述的xml格式基本涵盖了标签值、标签属性值、集合等内容,我们了解了针对特殊数据格式的处理,解析起来就没问题了,下面所讲的xml例子全部来源于上面的xml原始数据。
前置环境你需要导入xstream.jar的包
需要注意的细节- xml标签区分大小写,映射的时候不要认为它能够像sql一样,不管大小写
- xml标签对应实体属性,应确保数据类型是一致的,不然拿不到数据或者报错
下面将对常见的xml和后端java-model做一个对应格式映射
属性格式E37AA69997D0F399E040007F0100484D 20130809103931E37AA70270E78822E040007F01004851@gd.zg
上述这种xml标签是节点标签名称如
private String id; private String guid;对象格式
21800168@jm.gd.cp 测试用户2 2013-10-30 9:19:55
如上述的格式,它对应的就是
@XStreamAlias("prints")//标签名称是小写的prints,但是java对象声明是首字母大写不一致
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class Prints {
private String operuri;
private String opername;
//此处的注解也是别名替换,声明绑定xml标签时,使用operdate,而不是属性名operdate1
@XStreamAlias("operdate")
private String operdate1;
... (省略后续字段 及相关get/set方法)
}
接着,可以自己在对象里构建一个main方法做测试:
public static void main(String[] args) {
String xml= "21800168@jm.gd.cp 测试用户2 2013-10-30 9:19:55 ";
//com.leadal.csa.common.utils.XmlUtil
Prints prints = (Prints) XmlUtil.Xml2Object(xml, Prints.class);
System.out.println(prints);
}
好了,完成了第一个转换测试,接下来要继续介绍另一种对象格式的解析。
按照之前的理解,创建这个标签应该叫
@XStreamAlias("site")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class Site {
@XStreamAsAttribute
private String type;
@XStreamAsAttribute
private String uri;
... (省略后续字段 及相关get/set方法)
上述第一种方式就是在属性值上添加@XStreamAsAttribute注解,可以实现提取
@XStreamAlias("site")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter.class)
public class Site {
private String type;
private String uri;
... (省略后续字段 及相关get/set方法)
而第二种方式,属于全局设置,更改类上面@XStreamConverter注解中的转换器ToAttributedValueConverter.class,可完成提取
如上述所见的格式,
@XStreamAlias("status")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class SendDocStatus {
@XStreamAsAttribute
private String exchid;
@XStreamImplicit //修饰site对应的标签是集合,会出现多个
private List site;
...(省略后续字段 及相关get/set方法)
如上述代码,@XStreamImplicit完成了对集合类型的修饰,如果不声明该注解,可以试试解析会报什么错,应该会提醒你标签重复了,因为程序不知道它是集合类型,无法接收到。
具体操作首先我们得有一个概念:在java里,一切都是对象,xml数据也不例外。
那么,我们要针对xml标签名称去创建对应的实体对象
如下图,先创建一个实体对象,将xml的对象对应到了该对象上,要求是数据格式一致。(这里只抽取了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yXuVPQH9-1637921539708)(file:///C:/Users/Dell/Desktop/工作文档/blog/xml/xml1.png)]
结合前面的格式讲解,现在再根据这个图的指向,应该能清楚xml和java实体是如何对应的了。
关于如何调用API在java实体与xml数据之间转换,看下面的例子,使用的均是
com.leadal.csa.common.utils.XmlUtil
String xml= "常见异常错误 No such field xxx"; //xml数据 转 java实体 Prints prints = (Prints) XmlUtil.Xml2Object(xml, Prints.class); //java实体 转 xml数据 XmlUtil.Object2Xml(prints, prints.getClass()); 21800168@jm.gd.cp 测试用户2 2013-10-30 9:19:55
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field com.leadal.csa.common.model.SendDocStatus.status
该错误是找不到对应的字段,如上述的错误案例,是找不到SendDocStatus.status下面的这个status属性。
通常这种错误,去检查字段属性名称是否拼错了,或者是否加了别名属性声明,导致最后无法与标签名称绑定上。
Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field print
这个错误,翻译过来是重复字段print,意思就是print这个属性重复出现了,但你的接收类型装不下多个,这种情况就要看自己是不是要根据xml结构,去把这个print变成集合。
我们看一下原始数据关于print的描述:
...... ...
出现了2次这个标签,并且是以标签属性的方式设置值的,那么怎么设置类型才能将其成功封装到外部的
@XStreamAlias("prints")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
public class Prints {
@XStreamImplicit//此注解就是集合注解,参数名正好与标签名一致
private List print;
....(省略后续字段 及相关get/set方法)
}
@XStreamAlias("print")
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.ToAttributedValueConverter.class)
public class Print {
private String num;
....(省略后续字段 及相关get/set方法)
}
写在最后
以上就是关于如何解析xml的方式方法和将对象转成xml的方式,有问题可以再详细沟通,会使用到的注解我在下面统一列出并加上注释。
本文注解//声明当前对象或属性名称的别名,必须与xml标签名一致,区分大小写
@XStreamAlias("prints")
//声明xml解析转换器,
//JavaClassConverter是普通java对象转换器
//ToAttributedValueConverter是适用于标签内属性值较多的转换器
@XStreamConverter(value=com.thoughtworks.xstream.converters.extended.JavaClassConverter.class)
//集合类型声明
@XStreamImplicit



