Android pull封裝,直接解析xml

[java] 
         好久沒寫過博文瞭,最近在做xml方面的解析,xml的解析一直都是比較繁瑣的,所以對android的 pull進行瞭簡單的封裝,不用再為每個xml都創建解析類,但目前隻實現瞭對xml的簡單實現,主要通過反射來實現 
        能解析的xml形式主要有如下幾種,復雜的暫未支持
[html]
<?xml version="1.0" encoding="UTF-8"?> 
<list> 
    <user id="1">  www.aiwalls.com
        <userName>張三</userName> 
        <email>zhangsan@xxx.com</email> 
    </user> 
    <user> 
        <id>2</id> 
        <userName>李四</userName> 
        <email>lisi@xxx.com</email> 
    </user> 
    <user> 
        <id>3</id> 
        <userName>王五</userName> 
        <email>wangwu@xxx.com</email> 
    </user> 
</list> 

對應的java類如下:
[java] 
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; 
    } 
      
      

支持簡單的對象解析
[html]
<?xml version="1.0" encoding="UTF-8"?> 
<menu> 
    <id>1</id> 
    <code>1002</code> 
    <name>測試</name> 
</menu> 

或者
[html] 
<?xml version="1.0" encoding="UTF-8"?> 
<menu id="1" code="1002"> 
    <name>測試</name> 
</menu> 

對應的java類如下:
[java
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; 
    } 
      

支持對象中有list列表的解析
[java]
<?xml version="1.0" encoding="UTF-8"?> 
<parent> 
    <total>33</total> 
    <list> 
        <user> 
            <id>1</id> 
            <userName>張三</userName> 
            <email>zhangsan@xxx.com</email> 
        </user> 
        <user id="2"> 
            <userName>李四</userName> 
            <email>lisi@xxx.com</email> 
        </user> 
        <user id="3" userName="王五"> 
            <email>wangwu@xxx.com</email> 
        </user> 
    </list> 
</parent> 

對應的java類如下:
[java]
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解析器代碼如下:
[java] 
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()); 
        } 
    } 
  

發佈留言