`
peirubing
  • 浏览: 32020 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

XmlParser(android 解析xml)

 
阅读更多



import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

import android.util.Log;


public class XmlParser
{
    private static final String TAG = "XmlParser";

    /**
     * set方法前缀
     */
    private static final String SET_METHOD_PRE = "set";

    /**
     * 列表对象后缀
     */
    private static final String LIST_METHOD_SUFFIX = "List";

    /**
     * whoInfo列表tag
     */
    private static final String LIST_WHO = "whoInfoList";

    /**
     * Xml解析器
     */
    private XmlPullParser xmlParser = null;

    /**
     * 返回对象类
     */
    private Class<?> resultClazz = null;

    /**
     * 返回对象对应xml节点
     */
    private String resultNode = null;

    /**
     * 返回对象
     */
    private Object result = null;

    /**
     * 根元素列表
     */
    @SuppressWarnings("rawtypes")
    private List itemList = new ArrayList();

    /**
     * 根元素
     */
    private Object item = null;

    /**
     * 根元素类
     */
    private Class<?> itemClazz = null;

    /**
     * 根元素节点
     */
    private String itemNode = null;

    /**
     * 子元素列表
     */
    @SuppressWarnings("rawtypes")
    private List subItemList = new ArrayList();

    /**
     * 子元素
     */
    private Object subItem = null;

    /**
     * 子元素类
     */
    private Class<?> subItemClazz = null;

    /**
     * 子元素节点
     */
    private String subItemNode = null;

    /**
     * 子元素列表节点
     */
    private String subItemListNode = null;

    /**
     * 内嵌元素节点
     */
    private String innerItemNode = null;

    /**
     * 内嵌元素
     */
    private Object innerItem = null;

    /**
     * 内嵌元素类
     */
    private Class<?> innerItemClazz = null;

    /**
     * 是否开始解析返回对象
     */
    private boolean isResultStart = false;

    /**
     * 是否开始解析元素
     */
    private boolean isItemStart = false;

    /**
     * 是否开始解析返回子元素
     */
    private boolean isSubStart = false;

    /**
     * 是否开始解析返回内嵌对象元素
     */
    private boolean isInnerItemStart = false;

    public XmlParser(InputStream src, Class<?> relsultClazz, String resultNode)
    {
        if (src == null)
        {
            throw new IllegalArgumentException("InputStream can't be null");
        }
        if (relsultClazz == null)
        {
            throw new IllegalArgumentException("Class Instance can't be null");
        }

        this.resultClazz = relsultClazz;
        this.resultNode = resultNode;

        try
        {
            xmlParser = XmlPullParserFactory.newInstance().newPullParser();
            xmlParser.setInput(src, "UTF-8");
        }
        catch (XmlPullParserException e)
        {
            Log.e(TAG, "XmlPullParserException:" + e.getMessage(), e.getCause());
        }
    }

    /**
     *
     * 解析xml
     *
     * @return 对象列表
     */
    @SuppressWarnings(
    {"unchecked", "rawtypes"})
    public Object parseXml()
    {

        try
        {
            int evtType = xmlParser.getEventType();
            Field[] resultFields = resultClazz.getDeclaredFields();
            Field[] itemFields = null;
            Field[] innerItemFields = null;
            Field[] subItemFields = null;
            Field[] curFields = resultFields;
            while (evtType != XmlPullParser.END_DOCUMENT)
            {
                switch (evtType)
                {
                    case XmlPullParser.START_TAG:
                    {
                        String startTag = xmlParser.getName();

                        // 开始遍历返回对象
                        if (startTag.equalsIgnoreCase(resultNode))
                        {
                            result = newInstance(resultClazz);
                            evtType = xmlParser.next();
                            isResultStart = true;
                            continue;
                        }

                        // 开始遍历元素
                        if (itemNode != null
                                && startTag.equalsIgnoreCase(itemNode))
                        {
                            isItemStart = true;
                            if (itemClazz == null)
                            {
                                throw new IllegalArgumentException(
                                        "itemClazz can't be null");
                            }
                            else
                            {
                                item = newInstance(itemClazz);
                            }
                            itemFields = itemClazz.getDeclaredFields();
                            curFields = itemFields;
                            evtType = xmlParser.next();
                            continue;
                        }

                        // 开始遍历内嵌对象元素
                        if (innerItemNode != null
                                && startTag.equalsIgnoreCase(innerItemNode))
                        {
                            isInnerItemStart = true;
                            isItemStart = false;
                            innerItemClazz = getClass(innerItemNode);
                            innerItem = newInstance(innerItemClazz);
                            innerItemFields = innerItemClazz
                                    .getDeclaredFields();
                            curFields = innerItemFields;
                            evtType = xmlParser.next();
                            continue;
                        }

                        // 如果遍历至子对象列表处,初始化子对象
                        if (startTag.toLowerCase().endsWith(
                                LIST_METHOD_SUFFIX.toLowerCase())
                                && !startTag.trim().equals(LIST_WHO))
                        {
                            isSubStart = true;
                            String className = startTag.substring(
                                    0,
                                    startTag.toLowerCase().indexOf(
                                            LIST_METHOD_SUFFIX.toLowerCase()));

                            subItemNode = className;
                            subItemListNode = startTag;
                            subItemList = new ArrayList();

                            subItemClazz = getClass(className);
                            subItem = newInstance(subItemClazz);
                            subItemFields = subItemClazz.getDeclaredFields();
                            curFields = subItemFields;

                            evtType = xmlParser.next();
                            continue;

                        }

                        // 如果该节点和子对象相同则创建子对象实例
                        if (startTag.equals(subItemNode) && isSubStart)
                        {
                            subItem = newInstance(subItemClazz);
                            evtType = xmlParser.next();
                            continue;
                        }

                        // 开始遍历返回对象属性
                        for (Field field : curFields)
                        {
                            String fieldname = field.getName();
                            if (fieldname.equals(startTag))
                            {
                                try
                                {

                                    String methodName = SET_METHOD_PRE
                                            + fieldname.substring(0, 1)
                                                    .toUpperCase()
                                            + fieldname.substring(1);
                                    String nextText = xmlParser.nextText();

                                    if (isResultStart && !isItemStart && !isInnerItemStart)
                                    {
                                        invokeMethod(result, methodName,
                                                String.class, resultClazz,
                                                nextText);

                                    }
                                    else if (isItemStart && !isSubStart)
                                    {
                                        invokeMethod(item, methodName,
                                                String.class, itemClazz,
                                                nextText);
                                    }
                                    else if (isInnerItemStart && !isSubStart)
                                    {
                                        invokeMethod(innerItem, methodName,
                                                String.class, innerItemClazz,
                                                nextText);
                                    }
                                    else if (isSubStart)
                                    {
                                        invokeMethod(subItem, methodName,
                                                String.class, subItemClazz,
                                                nextText);
                                    }

                                    break;
                                }
                                catch (IllegalArgumentException e)
                                {
                                    Log.e(TAG,
                                            "IllegalArgumentException:"
                                                    + e.getMessage(),
                                            e.getCause());
                                }

                            }

                        }

                        break;
                    }
                    case XmlPullParser.END_TAG:
                    {
                        String endTag = xmlParser.getName();

                        // 一个根元素遍历结束加入根元素列表
                        if (endTag.equalsIgnoreCase(itemNode))
                        {
                            // 将返回对象元素加进列表
                            itemList.add(item);
                        }

                        // 一个子元素遍历结束加入子元素列表
                        else if (endTag.equalsIgnoreCase(subItemNode))
                        {
                            // 将子元素加进子列表
                            subItemList.add(subItem);
                        }

                        // 所有子元素遍历结束
                        else if (endTag.equalsIgnoreCase(subItemListNode))
                        {
                            String methodName = SET_METHOD_PRE
                                    + subItemListNode.substring(0, 1)
                                            .toUpperCase()
                                    + subItemListNode.substring(1);

                            // 内嵌对象内列表元素,调用内嵌对象的添加列表方法
                            // 否则调用根对象添加列表方法
                            if (!isInnerItemStart)
                            {
                                invokeMethod(item, methodName, ArrayList.class,
                                        itemClazz, subItemList);
                                isSubStart = false;
                                curFields = itemFields;
                            }
                            else
                            {
                                invokeMethod(innerItem, methodName,
                                        ArrayList.class, innerItemClazz,
                                        subItemList);
                                isSubStart = false;
                                isInnerItemStart = false;
                                curFields = innerItemFields;
                            }

                        }

                        // 内嵌对象遍历结束
                        else if (endTag.equalsIgnoreCase(innerItemNode))
                        {
                            String methodName = SET_METHOD_PRE
                                    + innerItemNode.substring(0, 1)
                                            .toUpperCase()
                                    + innerItemNode.substring(1);
                            invokeMethod(item, methodName, innerItemClazz,
                                    itemClazz, innerItem);
                            curFields = itemFields;
                            isInnerItemStart = false;
                            isItemStart = true;
                        }

                        // 所有节点遍历结束
                        else if (endTag.equalsIgnoreCase(resultNode)
                                && itemNode != null)
                        {
                            String itemName = itemClazz.getSimpleName();
                            String itemListMethodName = SET_METHOD_PRE
                                    + itemName.substring(0, 1).toUpperCase()
                                    + itemName.substring(1)
                                    + LIST_METHOD_SUFFIX;
                            invokeMethod(result, itemListMethodName,
                                    List.class, resultClazz, itemList);
                        }

                        break;
                    }
                    default:
                    {
                        break;
                    }
                }

                evtType = xmlParser.next();

            }
            return result;

        }
        catch (XmlPullParserException e)
        {
            Log.e(TAG, "InstantiationException:" + e.getMessage(), e.getCause());
        }
        catch (IOException e)
        {
            Log.e(TAG, "IOException:" + e.getMessage(), e.getCause());
        }
        catch (SecurityException e)
        {
            Log.e(TAG, "SecurityException:" + e.getMessage(), e.getCause());
        }

        return null;
    }

    public void setInnerItemNode(String innerItemNode)
    {
        this.innerItemNode = innerItemNode;
    }

    public void setItemNode(String itemNode)
    {
        this.itemNode = itemNode;
    }

    public void setItemClazz(Class<?> itemClazz)
    {
        this.itemClazz = itemClazz;
    }

    /**
     *
     * 根据类名创建类
     *
     * @param className
     *            类名
     */
    private Class<?> getClass(String className)
    {
        try
        {
            // 和返回对象在同一个包下
            String wholeClassName = resultClazz.getPackage().getName()
                    .replace(".result", "")
                    + "."
                    + className.substring(0, 1).toUpperCase()
                    + className.substring(1);

            return Class.forName(wholeClassName);

        }
        catch (ClassNotFoundException e)
        {
            Log.e(TAG, "ClassNotFoundException:" + e.getMessage(), e.getCause());
        }
        return null;
    }

    /**
     *
     * 调用类内方法
     *
     * @param o
     *            类对象
     * @param methodName
     *            方法名
     * @param parameterTypes
     *            参数类型
     * @param receiver
     *            类
     * @param value
     *            参数值
     */
    private void invokeMethod(Object o, String methodName,
            Class<?> parameterTypes, Class<?> receiver, Object value)
    {
        try
        {
            Method method = receiver.getMethod(methodName, parameterTypes);
            method.invoke(o, value);
        }
        catch (SecurityException e)
        {
            Log.e(TAG, "SecurityException:" + e.getMessage(), e.getCause());
        }
        catch (NoSuchMethodException e)
        {
            Log.e(TAG, "NoSuchMethodException:" + e.getMessage(), e.getCause());
        }
        catch (IllegalArgumentException e)
        {
            Log.e(TAG, "IllegalArgumentException:" + e.getMessage(),
                    e.getCause());
        }
        catch (IllegalAccessException e)
        {
            Log.e(TAG, "IllegalAccessException:" + e.getMessage(), e.getCause());
        }
        catch (InvocationTargetException e)
        {
            Log.e(TAG, "InvocationTargetException:" + e.getMessage(),
                    e.getCause());
        }
    }

    /**
     * 根据类创建对象实例
     *
     * @param cls
     *            对象类
     * @return
     */
    private Object newInstance(Class<?> cls)
    {
        try
        {
            return cls.newInstance();
        }
        catch (IllegalAccessException e)
        {
            Log.e(TAG, "IllegalAccessException:" + e.getMessage(), e.getCause());
        }
        catch (InstantiationException e)
        {
            Log.e(TAG, "InstantiationException:" + e.getMessage(), e.getCause());
        }
        return null;
    }

}

分享到:
评论

相关推荐

    xml.rar_Android XML_android_java xml parser

    除了解析XML,Android也提供了`XmlSerializer`类用于生成XML。开发者可以通过调用`startElement()`、`endElement()`和`text()`方法来构造XML文档。 六、优化与注意事项 - 在处理大文件时,避免使用DOM解析器,因为...

    XMLParser:Android 官方的pull解析XmlDemo

    Android 官方的pull解析XmlDemo 1. 选择解析器 Choose a Parser 官方推荐XmlPullParser,其在android中对XML的解析是高效且可维护的。android已经拥有该接口的两个实现: KXmlParser,通过XmlPullParserFactory....

    android下解析xml文件的demo

    本教程将详细介绍如何在Android环境下解析XML文件,以"ReadXMLDemo"为例,展示具体步骤和关键知识点。 首先,XML(eXtensible Markup Language)是一种自定义标记语言,它的结构清晰,易于读写,适合于数据交换和...

    xml-parser解析

    在Android平台上,处理XML数据是常见的任务,其中SAX(Simple API for XML)Parser是一种高效的解析方式,尤其适合处理大体积的XML文件。 SAX解析器采用事件驱动的方式工作,它读取XML文档时,遇到每个元素、属性或...

    android xml pull解析示例

    在Android系统中,XML Pull解析是一种轻量级且高效的解析XML文档的方法,它允许应用程序按需读取XML文档的节点,而无需加载整个文档到内存中。以下是关于Android XML Pull解析的详细知识讲解。 1. **XML Pull解析器...

    在android中使用pull解析xml文件

    本文将深入探讨如何在Android中使用Pull解析器解析XML文件。 一、XML Pull解析器简介 XML Pull解析器(XML Pull API)是一种基于事件驱动的解析模型,它不需预先加载整个XML文档,而是逐行读取,当遇到特定的XML...

    android 解析XML文件 生成XML文件

    本文将深入探讨如何使用SAX、DOM和Pull解析器解析XML文件,以及如何生成XML文件。我们将同时展示Java和Kotlin两种语言的实现方法。 一、SAX解析XML文件 SAX(Simple API for XML)是一种事件驱动的解析器,它不会一...

    Android解析XML使用WebView显示

    以上就是“Android解析XML并使用WebView显示”的主要技术点,开发者需要理解并掌握这些知识点,才能在实际项目中顺利实现这一功能。通过不断实践和学习,我们可以更好地理解和运用这些工具,提升应用的质量和用户...

    Android解析xml的Demo

    在Android开发中,XML(可扩展...在"Android解析xml的Demo"中,你可以找到这三种解析方式的具体实现,通过查看和运行代码,加深对XML解析的理解。同时,这个Demo也可以作为工具,帮助你在项目中快速集成XML解析功能。

    Android 解析xml文件

    本篇将深入探讨Android中解析XML文件的方法,以及如何通过示例代码`ReadXmlConfigFile`来实现这一过程。 ### XML解析器类型 Android提供了多种解析XML的方式,主要包括以下几种: 1. **DOM解析器**:Document ...

    android xml多种解析生成

    Android XML 多种解析生成 Android 平台中,XML 文件解析和生成是非常重要的一部分。XML 文件可以存储和交换结构化数据,广泛应用于 Android 应用程序中。本文将介绍 Android 中使用多种解析和生成 XML 文件的方法...

    android XML三种解析及生成

    3. 调用`parse`方法解析XML文件,并传入自定义的处理器对象。 ### 2. Pull Parser解析 Pull Parser与SAX类似,也是事件驱动的,但它提供了更简单的API,开发者可以主动调用`next()`方法获取下一个事件,无需实现...

    PullParser2_1_7.tgz_PullParser2_1_7_xml parser_xml x_xml解析器

    在实际应用中,例如Android开发中,PullParser2_1_7可以用来解析XML配置文件、XML数据流,或者在任何需要高效处理XML的场景下使用。开发者可以根据项目需求,通过集成这个库来优化XML处理流程,提高程序性能。

    android中xml文件的解析.doc

    理解如何解析XML文件是至关重要的,本节将深入探讨Android中的三种XML解析方法:SAX、DOM和Pull解析。 **SAX解析** SAX(Simple API for XML)是一种基于事件驱动的解析方式,它不加载整个XML文档到内存,而是逐行...

    android XML本地解析实例

    2. 解析XML时要处理异常,如`IOException`, `ParserConfigurationException`, `SAXException`等。 3. 在处理XML内容时,注意数据类型转换,例如字符串转整数、浮点数等。 4. 对于大量数据,优先考虑SAX或Pull解析以...

    六,Android Xml解析

    XML解析是将XML文档转换为Java对象的过程,这对于Android应用程序的资源配置、布局定义以及数据交换至关重要。这篇博文将深入探讨Android中的XML解析机制,包括DOM、SAX和Pull解析器三种主要方法。 首先,我们来看...

    Android中,使用SAX和PULL解析天气预报XML

    该文章详细介绍了在Android环境下如何使用SAX和PULL解析XML,包括代码示例和步骤说明,对于初学者来说非常有帮助。 最后,压缩包中的"Weather"文件很可能是示例的天气预报XML数据。通过实际解析这个文件,你可以更...

    Android XML 解析笔记

    #### DOM解析XML DOM(Document Object Model)解析是一种将整个XML文档加载到内存中,并构建出一棵树状结构(称为DOM树)的方法。这种模型使得开发者可以通过遍历DOM树来访问和修改XML文档的任何部分。然而,这种...

    Android解析xml(3)---Pull解析

    本篇文章将重点讨论如何在Android中使用Pull解析器(PullParser)来解析XML文件。Pull解析器是一种事件驱动的解析方式,它允许应用程序在解析过程中按需获取XML数据,而不是一次性加载整个文档到内存,这使得处理...

    解析xml文件 android

    本篇将详细介绍如何在Eclipse中解析XML文件,以及相关的Android XML解析技术。 首先,Android SDK提供了两种主要的XML解析方法:DOM(Document Object Model)和SAX(Simple API for XML)。DOM解析器将整个XML文件...

Global site tag (gtag.js) - Google Analytics