大家好,最近项目中需要用到对xml数据的序列化和反序列化,综合对比后决定用XStream进行xml的解析和生成工作,但是之间还是遇到了一些问题:

  1. XStream的远程依赖出现的问题。
  2. XStream的xml中有下划线的问题类。
  3. XStream的xml中有参数的序列化和反序列化的问题。
    下面就分享一下问题解决的方式:

一、就是Android Studio中的远程依赖出的问题。下面是我的app的build.gradle依赖:

android 解析url android 解析xml中文异常_xml解析

我在导入依赖包后一直报以下错误:

android 解析url android 解析xml中文异常_下划线问题_02


理论上来说我没有使用XmlPull和xpp3的依赖和jar包啊,怎么会说是依赖冲突出现的问题呢?

之后就试了试通过xstream的1.3.1解决问题,问题是解决了,但是在使用1.3.1之后没办法使用注解,debug发现执行到xstream.autodetectAnnotations(true);xstream.processAnnotations(TrainData2.class);时直接崩溃,经跟踪发现1.3.1没有对configuration进行初始化工作,对注解的支持欠佳。所以干脆还是乖乖使用1.4.8的版本吧。

接着把AS切换到project的模式下,打开项目下的External Libraries后发现了xpp3和xmlpull的依赖。经分析发现,安卓自带的有xmlPull解析工具,这就和XStream自带的xpp(全称是Xml Pull Parse)解析工具出现了XmlPull的冲突,这就能够解释为什么一直报依赖冲突的错误了。

知道问题所在那么就简单了,直接通过exclude进行依赖排除就行了,这时,我们排除系统的xmlPull,由于这个是需要在编译和运行时都要排除所以需要通过all*来标识是全过程的排除,不仅仅是在编译时排除。需要在build.gradle中进行但是通过在app的build.gradle中添加

configurations {
	        all*.exclude group: 'xmlpull', module: 'xmlpull'
	    		}

后完美解决依赖报错的问题。

二、接着就处理xml标签中有下划线的问题。当我对java对象经过序列化后,生成的xml中,之前的单下划线就会变成双下划线。1、序列化后本来的应该是下面内容:

android 解析url android 解析xml中文异常_下划线问题_03


可是经序列化后成了下面这种:

android 解析url android 解析xml中文异常_xml解析_04


2、同时对xml文件进行反序列化时,获取到的java对象的参数总是为null,这就有点儿坑了啊。反序列化后本来应该是这种:

TrainData(Train_ID=10, UpdateTrigger=101124, Train_Service_Number=1078524, 
			Destination_ID=100000001, Driver_Number=1045875, Station_ID=100212356, 
			Station_ID_in_up_side=175860, Station_ID_in_down_side=1089301, Direction=100000005, 
			On_TurnBack_Track_Flag=112, On_Platform_Flag=11)

可是却成了这种:

TrainData(Train_ID=null, UpdateTrigger=101124, Train_Service_Number=1078524, 
			Destination_ID=100000001, Driver_Number=1045875, Station_ID=100212356, 
			Station_ID_in_up_side=175860, Station_ID_in_down_side=1089301, Direction=100000005, 
			On_TurnBack_Track_Flag=112, On_Platform_Flag=11)

很明显是不对的。

不过进入XStream源码中发现了Xstream创建的时候其实有几种方式:

第一种是:XStream xstream = new XStream(); 第二种是:XStream xstream = new XStream(new DomDriver());

第三种是:XStream xstream = new XStream() { @Override protected MapperWrapper wrapMapper(MapperWrapper next) { return new MapperWrapper(next) { @Override public boolean shouldSerializeMember(Class definedIn, String fieldName) { if (definedIn == Object.class) { return false; } return super.shouldSerializeMember(definedIn, fieldName); } }; } };

这几个也就第二种是有可定制的参数的,所以就进入DomDriver后发现有

android 解析url android 解析xml中文异常_xml解析_05


这么一个方法第一个参数很明显是编码方式,然后进入第二个发现了解决方法。进入XmlFriendlyReplacer后看到了它的注解:

android 解析url android 解析xml中文异常_XStream_06


划红线的就是问题解决办法,就是对下划线的一个替换工作。

然后就通过序列化生成xml文件:

android 解析url android 解析xml中文异常_xml解析_07


通过反序列化生成对象:

android 解析url android 解析xml中文异常_XStream_08


三、至于参数问题主要是:序列化的时候通过xstream的添加参数的行数进行添加和反序列化的时候实体类创建的时候的注解形式的实现代码有:

1、序列化时候:public void mashelJava(TrainData trainData){ XStream xStream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"))); xStream.processAnnotations(TrainData.class); xStream.autodetectAnnotations(true); xStream.useAttributeFor(TrainData.class, "Train_ID"); String toXML = xStream.toXML(trainData); }

其中的useAttributeFor就是使用添加的参数问题

2、反序列化的时候:public void unMashal(String xml){ XStream xstream = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_"))); xstream.autodetectAnnotations(true); xstream.processAnnotations(TrainData.class); TrainData trainData = (TrainData) xstream.fromXML(xml); }

这个数要是通过实体类创建的时候的注解进行的对应关系实现的,实体类:

android 解析url android 解析xml中文异常_android 解析url_09


目前为止也就将结束了,至于其他的map,List等类型的,以及一些Convert的使用都是比较容易理解的了,有问题还望多多指正,再见。