Retrofit 如何解析 xml

2,364 阅读3分钟
原文链接: blog.csdn.net

在一般开发当中,用的最多的要属json解析了,retrofit自带的json解析是GsonConverterFactory;当然,有些公司也会使用xml解析,retrofit中xml解析使用的是SimpleXmlConverterFactory;当然,有些奇葩点的公司就一会用json一会用xml。

废话不多说,直接上步骤。

1、依赖库

compile ('com.squareup.retrofit2:converter-simplexml:2.1.0'){
        exclude group: 'xpp3', module: 'xpp3'
        exclude group: 'stax', module: 'stax-api'
        exclude group: 'stax', module: 'stax'
    }

2、初始化

public <T> T createByXML(String baseUrl, Class<T> service){
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .client(okHttpClient)
                .addConverterFactory(SimpleXmlConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        return retrofit.create(service);
    }

这里的okHttpClient的初始化请各位自己实现吧,我这里就先简单贴出点代码了。

3、定义接口

public interface IUpdateApi {

    @POST("stb/getApkUpgradeInfor/{imei}/{ystenID}/{softCodeId}/{versionSeq}")
    Observable<XMLService> checkUpdate(@Path("imei") String imei, @Path("ystenID") String ystenID, @Path("softCodeId") String softCodeId, @Path("versionSeq") String versionSeq);

}

4、使用

IUpdateApi api = RetrofitClient.getInstance().createByXML(baseUrl, IUpdateApi.class);
            api.checkUpdate(imei, ystenID, softCodeId, versionSeq + "")
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Subscriber<XMLService>() {
                        @Override
                        public void onCompleted() {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onNext(XMLService xmlService) {
                            String state = xmlService.state;
                            Log.i(TAG, "state=" + state);
                            List<UpdateInfo> list = xmlService.updateInfos;
                            Log.i(TAG, "list.size=" + list.size());
                            if (list.size() == 0) {
                                return;
                            }
                            mUpdateInfo = list.get(0);
                            if (mUpdateInfo == null) {
                                return;
                            }
                            if (state.equals("upgrade")) {
                                // 如果有更新就提示
                                showUpdateDialog();
                            } else {

                                Toast.makeText(mActivity, R.string.checkupate_lasted,
                                            Toast.LENGTH_SHORT).show();

                            }
                        }
                    });

那么问题来了,这个返回的bean类应该怎么写呢?和json一样吗?

首先,我这里返回的xml是这样的:

<?xml version="1.0" encoding="UTF-8" ?>
<Service id="getApkUpgradeInfor">
    <state>upgrade</state>
    <upgrades>
        <upgrade platformId="shijia_mobile_gw" versionId="252" versionName="shijia_X3_6.4.161209_252" packageType="FULL" packageLocation="http://upaiyun.bcs.ottcn.com/x3/upgrade/shijia_X3_6.4.161209_252.apk" packageStatus="RELEASE" isForce="true" md5="ad7ca963f76388c2d0212d94a4d895c5" upgradeContent="功能优化,bug修复
"></upgrade>
    </upgrades>
</Service>
  • 步骤1
@Root(name = "Service", strict = false) //name:要解析的xml数据的头部
public class XMLService {
    @Element(name = "state")
    public String state;

    @ElementList(required = true, inline = true, entry = "upgrades")
    public List<UpdateInfo> updateInfos;
}
  • 步骤2
@Root(name = "upgrade", strict = false)
public class UpdateInfo {
    @Attribute(name = "platformId", required = true)
    @Path("upgrade")
    public String platformId;
    @Attribute(name = "versionId", required = true)
    @Path("upgrade")
    public String versionId;
    @Attribute(name = "versionName", required = true)
    @Path("upgrade")
    public String versionName;
    @Attribute(name = "packageType", required = true)
    @Path("upgrade")
    public String packageType;
    @Attribute(name = "packageLocation", required = true)
    @Path("upgrade")
    public String packageLocation;
    @Attribute(name = "packageStatus", required = true)
    @Path("upgrade")
    public String packageStatus;
    @Attribute(name = "isForce", required = true)
    @Path("upgrade")
    public String isForce;
    @Attribute(name = "md5", required = true)
    @Path("upgrade")
    public String md5;
    @Attribute(name = "upgradeContent", required = true)
    @Path("upgrade")
    public String upgradeContent;


}

这么定义就好了,个人感觉比json解析复杂不少,json解析因为android studio安装了jsonFormat的插件,所以都不用自己写,但是xml这块,每个节点都要自己判断,并且不能写内部类(比如updateInfo不能是XMLService的内部类)

上面需要注意几个注解:

  • ElementList:申明该元素是一个集合。
  • Element:申明该元素只是一个普通属性
  • inline=true:ElementList的一个属性,由于ElementList包了一层,如果为false将不能解析。
  • required = false: 实体类中有,xml中没有,且声明为@Element的,在@Element中加上required = false 即可。
  • @Root(strict = false):xml中有的元素,而实体类中没有,在实体类的@(Root)中加上strict = false 如 @Root(strict = false)即可。

参考博客:
blog.csdn.net/qqyanjiang/…