Android:利用xstream解析xml文件

来源:互联网 发布:qq空间皮肤psd源码 编辑:程序博客网 时间:2024/06/01 09:40

一、前言

利用xstream解析xml文件的文章网上有很多,自己也参考了不少,首先对这些默默奉献的猿们表示感谢!

由于我项目中服务器给我返回的xml需要解析成集合类型,且涉及标签内属性,折腾了一番,做个简单的记录,仅供参考!

一般常见的xml文件格式如下:


这种格式的解析是相对比较简单的,难度不大,参考网上的文章很容易解析成功。

然而有时候服务器端返回的xml文件并不是这种形式,可能是下面这种:


看起来简洁了不少,但解析起来却很容易发生解析异常。

二、使用xstrem

类似于解析json,有很多第三方解析工具类能快速简单地解析出想要的实体类,比如gson、fastjson等,xml也有xstream可以使用。

1.eclipse

导入jar的形式添加到库。

2.Android Studio

2.1 导入jar包并添加到库;

2.2 build.gradle文件中添加依赖。

三、解析xml

以解析第二种形式为例。

首先在这里提供一个xmlutils工具类:

3.1 xmlutils.class

import android.text.TextUtils;import android.util.Log;import com.thoughtworks.xstream.XStream;import com.thoughtworks.xstream.converters.basic.DoubleConverter;import com.thoughtworks.xstream.converters.basic.FloatConverter;import com.thoughtworks.xstream.converters.basic.IntConverter;import com.thoughtworks.xstream.converters.basic.LongConverter;import com.thoughtworks.xstream.io.xml.DomDriver;import java.io.ByteArrayInputStream;import java.io.IOException;import java.io.InputStream;/** * xml解析工具类 * */public class XmlUtils {    private final static String TAG = XmlUtils.class.getSimpleName();    /**     * 将一个xml流转换为bean实体类     *     * @param type     * @return     */    @SuppressWarnings("unchecked")    public static <T> T toBean(Class<T> type, InputStream is) {        XStream xmStream = new XStream(new DomDriver("UTF-8"));        // 设置可忽略为在javabean类中定义的界面属性        xmStream.ignoreUnknownElements();        xmStream.registerConverter(new MyIntCoverter());        xmStream.registerConverter(new MyLongCoverter());        xmStream.registerConverter(new MyFloatCoverter());        xmStream.registerConverter(new MyDoubleCoverter());        xmStream.processAnnotations(type);        T obj = null;        try {            obj = (T) xmStream.fromXML(is);        } catch (Exception e) {            Log.d(TAG, "解析xml发生异常:" + e.getMessage());        } finally {            if (null != is) {                try {                    is.close();                } catch (IOException e) {                    Log.d(TAG, "关闭流出现异常:" + e.getMessage());                }            }        }        return obj;    }    public static <T> T toBean(Class<T> type, byte[] bytes) {        if (bytes == null) return null;        return toBean(type, new ByteArrayInputStream(bytes));    }    public static <T> T toBean(Class<T> type, String str) {        if (TextUtils.isEmpty(str)) return null;        return toBean(type, new ByteArrayInputStream(str.getBytes()));    }    private static class MyIntCoverter extends IntConverter {        @Override        public Object fromString(String str) {            int value;            try {                value = (Integer) super.fromString(str);            } catch (Exception e) {                value = 0;            }            return value;        }        @Override        public String toString(Object obj) {            return super.toString(obj);        }    }    private static class MyLongCoverter extends LongConverter {        @Override        public Object fromString(String str) {            long value;            try {                value = (Long) super.fromString(str);            } catch (Exception e) {                value = 0;            }            return value;        }        @Override        public String toString(Object obj) {            return super.toString(obj);        }    }    private static class MyFloatCoverter extends FloatConverter {        @Override        public Object fromString(String str) {            float value;            try {                value = (Float) super.fromString(str);            } catch (Exception e) {                value = 0;            }            return value;        }        @Override        public String toString(Object obj) {            return super.toString(obj);        }    }    private static class MyDoubleCoverter extends DoubleConverter {        @Override        public Object fromString(String str) {            double value;            try {                value = (Double) super.fromString(str);            } catch (Exception e) {                value = 0;            }            return value;        }        @Override        public String toString(Object obj) {            return super.toString(obj);        }    }}
(由于不知道出处,未能注明作者)

也可以自行按照项目实际编写工具类,但要特别说明一点:如果实体类中使用了xstream的注解,则必须要是要使用“

xmStream.processAnnotations(type);
”,否则注解是无效的。
解析的实体类如下:

3.2 Usrs.class

package com.example.zhongyuxin1011.xmlparser;import com.thoughtworks.xstream.annotations.XStreamAlias;import com.thoughtworks.xstream.annotations.XStreamImplicit;import java.util.List;/** * Created by zhongyuxin1011 on 2017/4/29 0029. */@XStreamAlias("usrs")public class Usrs {    @XStreamImplicit(itemFieldName="Usr")    private List<Usr> usr;    public List<Usr> getUsrs() {        return usr;    }    public void setUsrs(List<Usr> usr) {        this.usr = usr;    }    @Override    public String toString() {        return "Usrs{" +                "usrs=" + usr +                '}';    }}

3.3 Usr.class

package com.example.zhongyuxin1011.xmlparser;import com.thoughtworks.xstream.annotations.XStreamAlias;import com.thoughtworks.xstream.annotations.XStreamAsAttribute;/** * Created by zhongyuxin1011 on 2017/7/8 0008. */@XStreamAlias("Usr")public class Usr {    @XStreamAsAttribute()    private String name;    @XStreamAsAttribute()    private String status;    @XStreamAsAttribute()    private String rtsp;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getStatus() {        return status;    }    public void setStatus(String status) {        this.status = status;    }    public String getRtsp() {        return rtsp;    }    public void setRtsp(String rtsp) {        this.rtsp = rtsp;    }    @Override    public String toString() {        return "Usr{" +                "name='" + name + '\'' +                ", status='" + status + '\'' +                ", rtsp='" + rtsp + '\'' +                '}';    }}
这里需要注意的有两点:

1.如果类名或者属性名与xml文件中的不同,必须使用@XStreamAlias("[xml中的标签/属性名]")注解;

2.如果需要使用集合存储多个标签值(包含多个子标签),需要使用@XStreamImplicit(itemFieldName="[xml标签名]")注解。

(以上注解也可以通过代码给xstream设置相应的属性值)

四、一些疑惑

刚开始我的Usr类写在Usrs类里面,一直无法解析成功,直到偶然把Usr类独立出来才解析成功,不知道是不是xstream解析时不能识别内部类呢?如果你知道,还请不吝赐教!

五、例子源码

https://git.oschina.net/zhongyuxin1011/XmlParser.git

(如有错误之处,欢迎指正!)