1、为什么需要写一个通用xml解析方法。
当需要解析不同的xml节点。你有可能是在xml解析的时候匹配不同节点并且节点名都是写死的,这样的话你解析不同的节点就需要不同的解析方法。当然这种方式是最简单也是最笨的方法。为了减少代码把代码写得更有质量那么你就需要考虑设计一个通用的xml解析方法。
2、解析思路。
一般情况下,xml的解析结果最好放在一个实体类对象中,那样的话你使用起来非常方便(当然也更OO了),你也可以选择其他的方法把解析结果保存下来,不过个人觉得这种方式是比较好的。在解析过程中你需要做的是什么呢?这是解析的关键。其实就是把要解析的结果设置给对象的属性(成员变量),考虑到这点,那么肯定是需要知道对象有哪些属性啊,那就给实体类加一个方法(其实这里是做一定的规范)用于获得属性。知道了属性名以后下一步当然就是设置这些属性的值。因为不同的实体类的属性不同,所以设置值采用反射机制。大体上的思路就是这个样子。具体代码后面讲。
3、解析xml的格式类型。
文字只写两种xml格式的解析。其他格式你可以参考本文的思路任意发挥。
①只有节点中内容:如
①根据设计思路,你需要一个实体类,但是实体类有一定的规范(为了解析)。所以这些规范还需要实现一些统一的方法,于是就有了一个抽象类: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();
}
}
}
/***********************************************************
*@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" };
}
}
④最关键是如何解析。
/**
* @description :解析节点中的内容,封装成对象模型。
* @author : kwzhang
* @create :2013-2-28
* @param in
* @param obj
* @throws Exception
* @return :void
*/
public static
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(); } }
public static XmlPullParser pullParser;
static {
try {
pullParser = XmlPullParserFactory.newInstance().newPullParser();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
}
⑥说说另一种格式“只有节点属性”如何“通用”解析。为了方便下文做说明暂且把这种类型的xml称为“类型B”。下文所讲的都是针对类型B的相关代码。类型B的xml如下:
/***********************************************************
*@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" };
}
}
/**
* @description : 解析xml中的属性,封装成对象模型。
* @author : kwzhang
* @create :2013-2-28
* @param in
* @param obj
* @throws Exception
* @return :void
*/
public static
pullParser.setInput(in, encode);
int eventType = pullParser.getEventType();
ArrayList
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 obj = constructor.newInstance(); break; case XmlPullParser.END_TAG: break; } eventType = pullParser.next(); } return list; }
总结:虽然这里只是写了这两种类型,但是可以根据这种反射机制的思路完成更复杂的xml解析。使用的时候一定要注意变量命名的规范。用这样的方式进行解析的话代码设计更优雅,而且xml解析的时候会根据你的变量去解析,而不是写死。
转载自:http://www.cnblogs.com/vanezkw/archive/2013/03/03/2941496.html