论坛首页 移动开发技术论坛

Android黑群出品:对pull进行封装,可直接解析xml

浏览 4772 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-07-09  
android解析xml比较麻烦,针对每个xml文件,需要有专门的xml解析类。
现对pull进行了简单的封装,不用再给每个xml创建解析类,可以直接解析xml。

能解析的xml形式主要有如下几种,其他复杂格式暂未支持。
1、支持简单的列表解析
2、支持简单的对象解析
3、支持对象中包含List列表的解析


主要代码如下:
package com.juziku.demo.xml;
 
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
 
import org.xmlpull.v1.XmlPullParser;
 
import android.util.Log;
import android.util.Xml;
 
/**
 * 对pull解析xml进行了封装,不用给每个xml,再创建一个解析类
 *
 * @author steven
 *
 * http://www.juziku.com/sunlightcs/
 *
 */
public class XmlParse {
     
    /**
     * 解析XML
     * @param is        xml字节流
     * @param clazz     字节码      如:Object.class
     * @param startName       开始位置
     * @return          返回List列表
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List getXmlList(InputStream is, Class<?> clazz, String startName) {
        List list = null;
        XmlPullParser parser = Xml.newPullParser();
        Object object = null;
        try {
            parser.setInput(is, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();
 
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_DOCUMENT:
                        list = new ArrayList<Object>();
                        break;
                    case XmlPullParser.START_TAG:
                        //获得当前节点元素的名称
                        String name = parser.getName();
                        if (startName.equals(name)) {
                            object = clazz.newInstance();
                            //判断标签里是否有属性,如果有,则全部解析出来
                            int count = parser.getAttributeCount();
                            for(int i=0; i<count; i++)
                                setXmlValue(object, parser.getAttributeName(i), parser.getAttributeValue(i));
                        } else if (object != null) {
                            setXmlValue(object, name, parser.nextText());
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        if (startName.equals(parser.getName())) {
                            list.add(object);
                            object = null;
                        }
                        break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            Log.e("xml pull error", e.toString());
        }
        return list;
    }
     
     
     
    /**
     * 解析XML
     * @param is        xml字节流
     * @param clazz     字节码      如:Object.class
     * @return          返回Object
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Object getXmlObject(InputStream is, Class<?> clazz) {
        XmlPullParser parser = Xml.newPullParser();
        Object object = null;
        List list = null;
        Object subObject = null;
        String subName = null;
        try {
            parser.setInput(is, "UTF-8");
            //事件类型
            int eventType = parser.getEventType();
 
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    object = clazz.newInstance();
                    break;
                case XmlPullParser.START_TAG:
                    //获得当前节点元素的名称
                    String name = parser.getName();
                     
                    Field[] f = null;
                    if(subObject == null){
                        f = object.getClass().getDeclaredFields();
                         
                        //判断标签里是否有属性,如果有,则全部解析出来
                        int count = parser.getAttributeCount();
                        for(int j=0; j<count; j++)
                            setXmlValue(object, parser.getAttributeName(j), parser.getAttributeValue(j));
                    }else{
                        f = subObject.getClass().getDeclaredFields();
                    }
                     
                    for(int i = 0; i < f.length; i++){
                        if(f[i].getName().equalsIgnoreCase(name)){
                            //判断是不是List类型
                            if(f[i].getType().getName().equals("java.util.List")){
                                Type type = f[i].getGenericType();
                                if (type instanceof ParameterizedType) {
                                    //获得泛型参数的实际类型
                                    Class<?> subClazz = (Class<?>)((ParameterizedType)type).getActualTypeArguments()[0];
                                    subObject = subClazz.newInstance();
                                    subName = f[i].getName();
                                     
                                    //判断标签里是否有属性,如果有,则全部解析出来
                                    int count = parser.getAttributeCount();
                                    for(int j=0; j<count; j++)
                                        setXmlValue(subObject, parser.getAttributeName(j), parser.getAttributeValue(j));
                                     
                                    if(list == null){
                                        list = new ArrayList<Object>();
                                        f[i].setAccessible(true);
                                        f[i].set(object, list);
                                    }
                                }
                            }else{   //普通属性
                                if(subObject != null){
                                    setXmlValue(subObject, name, parser.nextText());
                                }else{
                                    setXmlValue(object, name, parser.nextText());
                                }
                            }
                            break;
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if (subObject != null && subName.equalsIgnoreCase(parser.getName())) {
                        list.add(subObject);
                        subObject = null;
                        subName = null;
                    }
                    break;
                }
                eventType = parser.next();
            }
        } catch (Exception e) {
            Log.e("xml pull error", e.getMessage());
        }
        return object;
    }
     
     
    /**
     * 把xml标签的值,转换成对象里属性的值
     * @param  t    对象
     * @param name   xml标签名
     * @param value  xml标签名对应的值
     */
    private void setXmlValue(Object t, String name, String value){
        try {
            Field[] f = t.getClass().getDeclaredFields();
            for(int i = 0; i < f.length; i++){
                if(f[i].getName().equalsIgnoreCase(name)){
                    f[i].setAccessible(true);
                    //获得属性类型
                    Class<?> fieldType = f[i].getType();
                     
                    if(fieldType == String.class) {
                        f[i].set(t, value);
                    }else if(fieldType == Integer.TYPE) {
                        f[i].set(t, Integer.parseInt(value));
                    }else if(fieldType == Float.TYPE) {
                        f[i].set(t, Float.parseFloat(value));
                    }else if(fieldType == Double.TYPE) {
                        f[i].set(t, Double.parseDouble(value));
                    }else if(fieldType == Long.TYPE) {
                        f[i].set(t, Long.parseLong(value));
                    }else if(fieldType == Short.TYPE) {
                        f[i].set(t, Short.parseShort(value));
                    }else if(fieldType == Boolean.TYPE) {
                        f[i].set(t, Boolean.parseBoolean(value));
                    }else{
                        f[i].set(t, value);
                    }
                }
            }
        } catch (Exception e) {
            Log.e("xml error", e.toString());
        }
    }
 
}



全文请访问:
http://www.juziku.com/sunlightcs/wiki/4489.htm
   发表时间:2012-07-10  
头像很好看 是楼主吗
0 请登录后投票
   发表时间:2012-07-10  
lonkiss 写道
头像很好看 是楼主吗

非本人,哈哈。。。
0 请登录后投票
   发表时间:2012-07-11  
头像给力,代码也给力
0 请登录后投票
   发表时间:2012-07-12  
myclover 写道
头像给力,代码也给力

每次解析XML的时候,都要写个解析类,太麻烦了,就简单的封装了一下,只能解析简单的XML
0 请登录后投票
   发表时间:2012-07-14  
sunlightcs 写道
lonkiss 写道
头像很好看 是楼主吗

非本人,哈哈。。。

看聚资网的全文链接。。 原来你是男的呀
0 请登录后投票
   发表时间:2012-07-16  
lonkiss 写道
sunlightcs 写道
lonkiss 写道
头像很好看 是楼主吗

非本人,哈哈。。。

看聚资网的全文链接。。 原来你是男的呀

哈哈   
0 请登录后投票
   发表时间:2012-07-20  
写的不错 和我现在用的基本一致,不过是用sax解析的。
我还添加了注解功能可以配置需要解析的字段。
0 请登录后投票
   发表时间:2012-08-27  
wxw404 写道
写的不错 和我现在用的基本一致,不过是用sax解析的。
我还添加了注解功能可以配置需要解析的字段。


对数据库进行了简单的封装,及通用功能的封装。
https://github.com/sunlightcs/juziku-android/
0 请登录后投票
   发表时间:2012-09-03   最后修改:2012-09-03
sunlightcs 写道
wxw404 写道
写的不错 和我现在用的基本一致,不过是用sax解析的。
我还添加了注解功能可以配置需要解析的字段。


对数据库进行了简单的封装,及通用功能的封装。
https://github.com/sunlightcs/juziku-android/


谢谢,有很多地方值得学习。
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics