热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

android通用xml解析方法

之前做的网络相关的应用,里面涉及到了xml的解析,由于急于完成任务也没有设计就直接敲代码。这几天给一个朋友做项目的时候也涉及到了xml的解析,而且解析的内容比较多,我查看了以前的项目中的相关代码,顿时觉得很多代码都是可以优化的。在此写两个通用的xml解析方法,当然这里所讲的通用只是在一定程度上并且需要遵守一些规范。

1、为什么需要写一个通用xml解析方法。

当需要解析不同的xml节点。你有可能是在xml解析的时候匹配不同节点并且节点名都是写死的,这样的话你解析不同的节点就需要不同的解析方法。当然这种方式是最简单也是最笨的方法。为了减少代码把代码写得更有质量那么你就需要考虑设计一个通用的xml解析方法。

2、解析思路。

一般情况下,xml的解析结果最好放在一个实体类对象中,那样的话你使用起来非常方便(当然也更OO了),你也可以选择其他的方法把解析结果保存下来,不过个人觉得这种方式是比较好的。在解析过程中你需要做的是什么呢?这是解析的关键。其实就是把要解析的结果设置给对象的属性(成员变量),考虑到这点,那么肯定是需要知道对象有哪些属性啊,那就给实体类加一个方法(其实这里是做一定的规范)用于获得属性。知道了属性名以后下一步当然就是设置这些属性的值。因为不同的实体类的属性不同,所以设置值采用反射机制。大体上的思路就是这个样子。具体代码后面讲。

3、解析xml的格式类型。

文字只写两种xml格式的解析。其他格式你可以参考本文的思路任意发挥。

①只有节点中内容:如

代码如下:

  30323

  10042



②只有节点属性:如

代码如下:

   

   

   



4、如何实现。

①根据设计思路,你需要一个实体类,但是实体类有一定的规范(为了解析)。所以这些规范还需要实现一些统一的方法,于是就有了一个抽象类:BaseObj。

代码如下:

BaseObj

/***********************************************************

 *@description : This class function is TODO

 *

 * @create author : kwzhang

 * @create date   :2013-2-28

 * @modify author :

 * @modify date   :

 * @contact: vanezkw@163.com

 *

 **********************************************************/

package com.vane.elearning.model;

 

import java.lang.reflect.Field;

 

/**

 * @author kwzhang

 *

 */

public abstract class BaseObj {

public abstract String[] getNodes();

public void setParamater(String tag, Object value) {

try {

Field field = getClass().getField(tag);

field.setAccessible(true);

field.set(this, value);

} catch (SecurityException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

} catch (IllegalArgumentException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

}

}

}


②根据具体的节点类型生成类的成员。这里先看看需要解析的xml。

代码如下:

 

  true

  10001

  高一年级

  10010

  高一(01)班

  10000

  张三

 


③对应的实体类。

代码如下:

View Code

/***********************************************************

 *@description : This class function is TODO

 *

 * @create author : kwzhang

 * @create date   :2013-2-28

 * @modify author :

 * @modify date   :

 * @contact: vanezkw@163.com

 *

 **********************************************************/

package com.vane.elearning.model;

import java.io.Serializable;

/**

 * @author kwzhang

 *

 */

public class Student extends BaseObj implements Serializable {

private static final long serialVersiOnUID= 1L;

public String GradeID, GradeName, ClassID, ClassName, UserID, UserName;

public Student() {

}

@Override

public String[] getNodes() {

return new String[] { "GradeID", "GradeName", "ClassID", "ClassName", "UserID", "UserName" };

}

}


实体类中的是这样规范的:getNodes()返回的是xml的节点名,命名必须相同,并且成员变量名必须和节点名相同。当然这里实现Serializable 接口只是我自己的项目中的需求而已,和本文无关。

④最关键是如何解析。

代码如下:

View Code

/**

 * @description :解析节点中的内容,封装成对象模型。

 * @author : kwzhang

 * @create :2013-2-28

 * @param in

 * @param obj

 * @throws Exception

 * @return :void

 */

public static void streamText2Model(InputStream in, T obj) throws Exception {

pullParser.setInput(in, encode);

int eventType = pullParser.getEventType();

String[] nodes = obj.getNodes();

String nodeName = null;

boolean success = true;

while (eventType != XmlPullParser.END_DOCUMENT && success) {

switch (eventType) {

case XmlPullParser.START_DOCUMENT:

break;

case XmlPullParser.START_TAG:

nodeName = pullParser.getName();

break;

case XmlPullParser.TEXT:

if ("IsLog".equals(nodeName) && pullParser.getText().equals("false")) {

success = false;

break;

}

for (int i = 0; i

if (nodes[i].equals(nodeName)) {

obj.setParamater(nodeName, pullParser.getText());

}

}

break;

case XmlPullParser.END_TAG:

break;

}

eventType = pullParser.next();

}

}


当然里面的一些变量在类初始化的时候就完成了。如下:

代码如下:

private static String encode = "utf-8";

public static XmlPullParser pullParser;

static {

try {

  pullParser = XmlPullParserFactory.newInstance().newPullParser();

  } catch (XmlPullParserException e) {

  e.printStackTrace();

}

}


⑤如何使用.如下:

代码如下:

XmlUtils.streamText2Model(result, ActMain.student);

很简单吧。result就是xml的数据流。具体的细节可以自己体会一下。这个解析类在一定程度上可以通用,也就是你的xml格式符合“只有节点中内容”那么就可以这么通用。为了方便下文做说明暂且把这种类型的xml称为“类型A”。

⑥说说另一种格式“只有节点属性”如何“通用”解析。为了方便下文做说明暂且把这种类型的xml称为“类型B”。下文所讲的都是针对类型B的相关代码。类型B的xml如下:

代码如下:

View Code

 

 

 

 

 

 


⑦类型B实体类如下:(其实和类型A是一样的)

代码如下:

View Code

/***********************************************************

 *@description : This class function is TODO

 *

 * @create author : kwzhang

 * @create date   :2013-2-28

 * @modify author :

 * @modify date   :

 * @contact: vanezkw@163.com

 *

 **********************************************************/

package com.vane.elearning.model;

import java.io.Serializable;

/**

 * @author kwzhang

 *

 */

public class Keli extends BaseObj implements Serializable {

private static final long serialVersiOnUID= 1L;

public String KeliName, KeliId, SubId, ExeTp, ExeType, ExeDt, ExeCount, SubName;

public Keli() {

}

@Override

public String[] getNodes() {

return new String[] { "KeliName", "KeliId", "SubId", "ExeTp", "ExeType", "ExeDt", "ExeCount", "SubName" };

}

}


⑧类型B解析方法如下:

代码如下:

View Code

/**

 * @description : 解析xml中的属性,封装成对象模型。

 * @author : kwzhang

 * @create :2013-2-28

 * @param in

 * @param obj

 * @throws Exception

 * @return :void

 */

public static List streamParam2Model(InputStream in, T obj) throws Exception {

pullParser.setInput(in, encode);

int eventType = pullParser.getEventType();

ArrayList list = new ArrayList(4);

String[] nodes = obj.getNodes();

while (eventType != XmlPullParser.END_DOCUMENT) {

switch (eventType) {

case XmlPullParser.START_DOCUMENT:

break;

case XmlPullParser.START_TAG:

String name = pullParser.getName();

boolean flag = false;

if (null == name || name.equals("")) {

break;

}

for (int i = 0; i

String value = pullParser.getAttributeValue(null, nodes[i]);

flag |= (null != value);

obj.setParamater(nodes[i], value);

}

if (flag) {

list.add(obj);

}

Constructor cOnstructor= (Constructor) obj.getClass().getConstructor();

obj = constructor.newInstance();

break;

case XmlPullParser.END_TAG:

break;

}

eventType = pullParser.next();

}

return list;

}


⑨如何使用类别B的解析。

代码如下:

ArrayList  datas = (ArrayList) XmlUtils.stream2Tm(result, new TmInfo());

总结:虽然这里只是写了这两种类型,但是可以根据这种反射机制的思路完成更复杂的xml解析。使用的时候一定要注意变量命名的规范。用这样的方式进行解析的话代码设计更优雅,而且xml解析的时候会根据你的变量去解析,而不是写死。

转载自:http://www.cnblogs.com/vanezkw/archive/2013/03/03/2941496.html


推荐阅读
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文详细分析了JSP(JavaServer Pages)技术的主要优点和缺点,帮助开发者更好地理解其适用场景及潜在挑战。JSP作为一种服务器端技术,广泛应用于Web开发中。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了如何使用ActionScript 3.0 (AS3) 连接并操作MySQL数据库。通过具体的代码示例和步骤说明,帮助开发者理解并实现这一过程。 ... [详细]
  • 在即将迎来26岁生日之际,作者的人生陷入了低谷。经过近三年的硕士学习后,最终决定退学,并且面临没有工作经验的困境。尽管如此,作者依然坚定地选择为自己的人生负责。 ... [详细]
  • 使用Python在SAE上开发新浪微博应用的初步探索
    最近重新审视了新浪云平台(SAE)提供的服务,发现其已支持Python开发。本文将详细介绍如何利用Django框架构建一个简单的新浪微博应用,并分享开发过程中的关键步骤。 ... [详细]
  • 本文详细介绍了美国最具影响力的十大财团,包括洛克菲勒、摩根、花旗银行等。这些财团在历史发展过程中逐渐形成,并对美国的经济、政治和社会产生深远影响。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 本题通过将每个矩形视为一个节点,根据其相对位置构建拓扑图,并利用深度优先搜索(DFS)或状态压缩动态规划(DP)求解最小涂色次数。本文详细解析了该问题的建模思路与算法实现。 ... [详细]
  • 本题探讨如何通过最大流算法解决农场排水系统的设计问题。题目要求计算从水源点到汇合点的最大水流速率,使用经典的EK(Edmonds-Karp)和Dinic算法进行求解。 ... [详细]
  • 在网页开发中,页面加载速度是一个关键的用户体验因素。为了提升加载效率,避免在PageLoad事件中进行大量数据绑定操作,可以采用异步加载和特定控件来优化页面加载过程。 ... [详细]
author-avatar
mobiledu2502931077
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有