Result
StuId30323/StuId
ClassID10042/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
/***********************************************************
*@description : This class function is TODO
*
* @create author : kwzhang
* @create date :2013-2-28
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)* @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。
代码如下:
?xml version="1.0" encoding="UTF-8" ?
DsXml
IsLogtrue/IsLog
GradeID10001/GradeID
GradeName高一年级/GradeName
ClassID10010/ClassID
ClassName高一(01)班/ClassName
UserID10000/UserID
UserName张三/UserName
/DsXml
③对应的实体类。
代码如下:
View Code
/***********************************************************
*@description : This class function is TODO
*
* @create author : kwzhang
* @create date :2013-2-28
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)* @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 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")) {
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)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
/***********************************************************
*@description : This class function is TODO
*
* @create author : kwzhang
* @create date :2013-2-28
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)* @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 T extends BaseObj ListT streamParam2Model(InputStream in, T obj) throws Exception {
pullParser.setInput(in, encode);
int eventType = pullParser.getEventType();
ArrayListT list = new ArrayListT(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);
}
ConstructorT constructor = (ConstructorT) obj.getClass().getConstructor();
obj = constructor.newInstance();
break;
case XmlPullParser.END_TAG:
break;
}
eventType = pullParser.next();
}
return list;
}
⑨如何使用类别B的解析。
代码如下:
ArrayListTmInfo datas = (ArrayListTmInfo) XmlUtils.stream2Tm(result, new TmInfo());
总结:虽然这里只是写了这两种类型,但是可以根据这种反射机制的思路完成更复杂的xml解析。使用的时候一定要注意变量命名的规范。用这样的方式进行解析的话代码设计更优雅,而且xml解析的时候会根据你的变量去解析,而不是写死。
转载自:http://www.cnblogs.com/vanezkw/archive/2013/03/03/2941496.html