文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

android通用xml解析方法

2022-06-06 10:53

关注

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

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

2、解析思路。

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

3、解析xml的格式类型。

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

①只有节点中内容:如

代码如下:
<?xml version="1.0" encoding="UTF-8" ?>

<Result>

  <StuId>30323</StuId>

  <ClassID>10042</ClassID>

</Result>

②只有节点属性:如

代码如下:
<?xml version="1.0" encoding="UTF-8" ?>

<Result>

   <ProjLst Name="测试1" Id="1" />

   <ProjLst Name="测试2" Id="2" />

   <ProjLst Name="测试3" Id="3" />

</Result>

4、如何实现。

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

代码如下:
BaseObj

package com.vane.elearning.model;

 

import java.lang.reflect.Field;

 

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。

代码如下:
<?xml version="1.0" encoding="UTF-8" ?>

  <DsXml>

  <IsLog>true</IsLog>

  <GradeID>10001</GradeID>

  <GradeName>高一年级</GradeName>

  <ClassID>10010</ClassID>

  <ClassName>高一(01)班</ClassName>

  <UserID>10000</UserID>

  <UserName>张三</UserName>

  </DsXml>

③对应的实体类。

代码如下:
View Code

package com.vane.elearning.model;

import java.io.Serializable;

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

public static <T extends BaseObj> 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 < nodes.length; 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

 <?xml version="1.0" encoding="UTF-8" ?>

  <DsXml>

  <ProjLst KeliName="测试1" KeliId="170" SubId="13" ExeTp="1" ExeType="预习" ExeDt="2013-2-27" ExeCount="4" SubName="信息技术" />

  <ProjLst KeliName="测试2" KeliId="154" SubId="13" ExeTp="1" ExeType="预习" ExeDt="2012-11-19" ExeCount="2" SubName="信息技术" />

  <ProjLst KeliName="测试2" KeliId="150" SubId="13" ExeTp="3" ExeType="课后" ExeDt="2012-11-15" ExeCount="2" SubName="信息技术" />

  </DsXml>

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

代码如下:
View Code

package com.vane.elearning.model;

import java.io.Serializable;

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

public static <T extends BaseObj> List<T> streamParam2Model(InputStream in, T obj) throws Exception {

pullParser.setInput(in, encode);

int eventType = pullParser.getEventType();

ArrayList<T> list = new ArrayList<T>(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 < nodes.length; i++) {

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

flag |= (null != value);

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

}

if (flag) {

list.add(obj);

}

Constructor<T> constructor = (Constructor<T>) obj.getClass().getConstructor();

obj = constructor.newInstance();

break;

case XmlPullParser.END_TAG:

break;

}

eventType = pullParser.next();

}

return list;

}

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

代码如下:
ArrayList<TmInfo>  datas = (ArrayList<TmInfo>) XmlUtils.stream2Tm(result, new TmInfo());

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

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

您可能感兴趣的文章:基于Android XML解析与保存的实现android layout XML解析错误的解决方法Android中使用sax解析xml文件的方法Android 解析XML 文件的四种方法总结Android中使用PULL方式解析XML文件深入介绍Android提高之XML解析与生成实例详解Android 使用Pull方法解析XML文件的方法android编程之XML文件解析方法详解(附源码)Android使用Pull解析器解析xml文件的实现代码19个Android常用工具类汇总android 一些工具类汇总Android开发中解析xml文件XmlUtils工具类与用法示例


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯