对pull进行封装,可直接解析xml

android解析xml比较麻烦,针对每个xml文件,需要有专门的xml解析类。
现对pull进行了简单的封装,不用再给每个xml创建解析类,可以直接解析xml,主要通过反射实现的。

能解析的xml形式主要有如下几种,其他复杂格式暂未支持。

能解析的xml形式主要有如下几种,其他复杂格式暂未支持。
1、支持简单的列表解析,如:
<?xml version="1.0" encoding="UTF-8"?>
<list>
    <user id="1">
        <userName>张三</userName>
        <email>[email protected]</email>
    </user>
    <user>
        <id>2</id>
        <userName>李四</userName>
        <email>[email protected]</email>
    </user>
    <user>
        <id>3</id>
        <userName>王五</userName>
        <email>[email protected]</email>
    </user>
</list>
对应的Java类如下:
package com.juziku.demo.xml;

public class User {
    private int id;
    private String userName;
    private String email;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    
    
}


2、支持简单的对象解析,如:
<?xml version="1.0" encoding="UTF-8"?>
<menu>
    <id>1</id>
    <code>1002</code>
    <name>测试</name>
</menu>

1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<menu id="1" code="1002">
    <name>测试</name>
</menu>

对应的Java类如下:
package com.juziku.demo.xml;

public class Menu {
    private int id;
    private int code;
    private String name;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
}


3、支持对象中包含List列表的解析,如:
<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <total>33</total>
    <list>
        <user>
            <id>1</id>
            <userName>张三</userName>
            <email>[email protected]</email>
        </user>
        <user id="2">
            <userName>李四</userName>
            <email>[email protected]</email>
        </user>
        <user id="3" userName="王五">
            <email>[email protected]</email>
        </user>
    </list>
</parent>

对应的Java类如下:
package com.juziku.demo.xml;

import java.util.List;

public class UserList {
    private int total;
    private List<User> user;
    public int getTotal() {
        return total;
    }
    public void setTotal(int total) {
        this.total = total;
    }
    public List<User> getUser() {
        return user;
    }
    public void setUser(List<User> user) {
        this.user = user;
    }
}


解析xml的代码如下所示:
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());
        }
    }

}

猜你喜欢

转载自edwinningb.iteye.com/blog/1666775