`
寻梦者
  • 浏览: 637382 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

android中如何更有效率得解析xml

阅读更多

     好久没写过博文了,最近在做xml方面的解析,xml的解析一直都是比较繁琐的,所以对android的 pull进行了简单的封装,不用再为每个xml都创建解析类,但目前只实现了对xml的简单实现,主要通过反射来实现

 

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

 

<?xml version="1.0" encoding="UTF-8"?>
<list>
    <user id="1">
        <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类如下:

 

 

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;
    }
     
     
}

支持简单的对象解析

 

 

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

或者

 

 

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

对应的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列表的解析

 

 

<?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类如下:

 

 

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解析器代码如下:

 

 

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());
        }
    }
 
}
分享到:
评论

相关推荐

    XML解析之SAX解析DEMO

    2. **创建解析器**: 使用`SAXParserFactory`创建`SAXParser`实例,然后通过`parse()`方法解析XML输入源。输入源可以是文件、流或者URL。 3. **事件处理**: 在解析过程中,SAX解析器会调用我们在`DefaultHandler`...

    应用源码之27.使用SAX解析XML.zip

    1. 在Android中,由于内存限制,对于大文件,使用SAX解析比DOM解析更有效率。 2. SAX解析是顺序的,因此解析过程中不能跳过任何元素。 3. 解析过程是线程安全的,可以在多个线程中同时解析不同的XML文件。 4. 在事件...

    JunitTest XML parse

    在JUnit测试中使用SAX解析XML,首先需要创建一个实现了`DefaultHandler`接口的类,重写相关事件处理方法,如`startElement()`、`endElement()`和`characters()`。然后,创建`SAXParser`并设置处理程序,最后调用`...

    移动RSS阅读器利用saxparser解析xml

    在处理大型XML文档时,SAX解析器比DOM(Document Object Model)更有效率,因为它不需要将整个文档加载到内存中。SAX解析器逐行读取XML文件,当遇到如开始元素、结束元素、文本等事件时,会触发相应的回调函数,这样...

    xml格式解析

    这种方法不需要一次性加载整个文档,因此对大型XML文件更有效率。然而,由于不能直接访问文档结构,处理数据可能更复杂,需要在事件回调中保持状态。 XML Pull解析是另一种解析方式,结合了DOM和SAX的优点。它允许...

    安卓svg解析

    在Android开发中,SVG的使用可以提供高质量的图形,特别是在高分辨率设备上,比传统的位图(Bitmap)更具有优势。"安卓svg解析"主要涉及以下几个关键知识点: 1. **SVG的基本概念**:SVG是一种开放标准的矢量图形...

    安卓网站交互JSONxmlWebserviceUPnP相关-AndroidUDP组播的例子包含Android组播Server和Client端发送端和接收端.zip

    这种方式相比单播和广播更有效率,因为它只需要发送一次数据,就能被多个接收者同时接收,减少了网络带宽的消耗。 在这个示例中,开发者可以学习到如何在Android应用中创建和管理UDP套接字,设置组播地址和端口,...

    Android 串口开发demo

    在Android应用中进行串口通信首先需要在`AndroidManifest.xml`文件中添加相应的权限声明。例如,`&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;` 和 `&lt;uses-feature android:name=...

    Android应用开发典型案例分析

    Android UI设计是基于用户界面(UI)的理论,其主要目的是让用户能够方便有效率地操作硬件,完成与设备的双向互动。 用户界面(UI)定义广泛,它不仅包括人机互动,还包括图形用户界面。在人类与机械的信息交流中,...

    Android应用源码之12.RelativeLayout.zip

    为了避免这种情况,可以考虑结合使用LinearLayout或其他布局,或者使用ConstraintLayout,它在处理复杂布局时通常更有效率。 5. **在Android Studio中的使用**: - Android Studio提供了可视化编辑器来方便地设计...

    android RS232串口读写程序

    以下是对这个"android RS232串口读写程序"的详细解析: 1. **RS232串口通信**: RS232是最早的标准串行接口之一,用于设备之间的通信。它定义了数据位、停止位、校验位、波特率等通信参数,并通过DB9或DB25连接器...

    android反编译工具

    在Android应用开发中,安全是...Apktool和Dex2jar是这个过程中的核心工具,正确使用和更新这些工具,可以帮助开发者更有效地进行APK分析。在遇到反编译异常时,及时检查工具版本和错误日志,通常能找到解决问题的线索。

    Android实现窗口抖动

    通过以上方法,开发者可以有效地避免和解决Android应用中的窗口抖动问题,提高用户体验和应用性能。在开发过程中,持续关注性能指标,如帧率(FPS)和主线程的CPU使用率,可以帮助及时发现和修复窗口抖动问题。

    android开发培训课件(详解).rar

    使用JUnit和Espresso进行单元测试和UI测试,使用Android Studio的调试工具进行问题排查,都是优化代码质量和提升开发效率的有效手段。 12. 性能优化 了解内存管理、CPU使用率、电量消耗和渲染性能等指标,通过...

    Android 英语单词记忆.rar

    深入研究这个源码,不仅可以帮助我们理解Android应用程序的开发流程,也能为设计更有效的英语学习工具提供启示。通过这样的实践,开发者能够提升自己的技能,同时为用户提供更高效、更具趣味性的学习体验。

    Android串口通信Demo

    本文将详细解析"Android串口通信Demo"的实现原理、关键步骤及注意事项,帮助开发者理解如何在Android应用中实现串口通信。 串口通信,也称为串行通信,是一种数据传输方式,通过串行数据线一次传输一个比特位。在...

    Android 串口开发 支持数据位 停止位 校验

    "ComTest"这个程序应该是一个实现了这些功能的实例,通过它,你可以了解如何在Android设备上进行串口通信,实现与外部设备的有效交互。在实际开发中,可能还需要考虑线程管理、缓冲区大小、超时设置等高级话题,以...

    基于netty与protobuf的Android手机视频实时传输

    相比XML或JSON等文本格式,Protobuf的二进制格式具有更小的体积,更快的解析速度,适合于实时传输大数据量的视频流。在本项目中,Android手机摄像头捕捉的视频数据被编码为Protobuf消息,然后发送到服务器。 **...

    Android ZBar二维码扫描

    在Android开发中,ZBar是一个常用的库,用于处理条形码和二维码的扫描与解析。本文将详细探讨ZBar在Android中的应用,包括其工作原理、集成步骤、使用方法以及如何从相册读取图片进行解析。 首先,ZBar是一个开源的...

    Android串口通信的标准格式代码

    3. **权限管理**:在AndroidManifest.xml中添加必要的权限,如`&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /&gt;`,因为串口可能位于USB端口,需要位置权限。 4. **数据发送解析**:在...

Global site tag (gtag.js) - Google Analytics