Android XML小工具
<b>一、概述</b>
XML与Object互相转化,支持8种基本类型、String和byte[]。byte[]需要经由base64编码(API8以后才有,之前版本可以自己拷入)。
更多代码及测试用例,见附件工程!
<b>二、Object –> XML</b>
public class XmlBuilder {
/**
* 由对象属性生成XML
*
* @param outs 输出流
* @param encoding 字符编码
* @param obj 对象
*/
public void buildXml(OutputStream outs, String encoding, Object obj)
throws IllegalArgumentException, IllegalStateException,
IOException, IllegalAccessException {
XmlSerializer serializer = Xml.newSerializer(); // 创建一个Xml序列化
serializer.setOutput(outs, encoding); // 设置输出流及字符编码
serializer.startDocument(encoding, true); // 开始文档
writeXml(serializer, obj); // 写文档
serializer.endDocument(); // 结束文档
outs.close(); // 关闭输出流
}
* 将对象属性写入XML
* @param serializer XML序列化
private void writeXml(XmlSerializer serializer, Object obj)
final String tag_type = "type";
final String tag_value = "value";
Class<?> cls = obj.getClass(); // 获取对象运行时类
String clsName = cls.getName(); // 获取对象名称
serializer.startTag(null, clsName);
Field[] fields = cls.getDeclaredFields(); // 返回类声明的所有字段
boolean isWrite;
Class<?> type; // 变量类型
String varName, typeName, value = null; // 变量名、类型名、变量值
for (Field field : fields) {
isWrite = true;
type = field.getType(); // 获取变量类型
typeName = type.getName(); // 获取类型名
field.setAccessible(true); // 设置变量可访问
if (type.isPrimitive()) { // 是否为基本类型
if (typeName.equals("boolean")) {
value = String.valueOf(field.getBoolean(obj));
} else if (typeName.equals("char")) {
// char型未赋值,为默认'\u0000'时,会影响parser.next()
char c = field.getChar(obj);
value = c == '\u0000' ? "null" : String.valueOf(field
.getChar(obj));
} else if (typeName.equals("byte")) {
value = String.valueOf(field.getByte(obj));
} else if (typeName.equals("short")) {
value = String.valueOf(field.getShort(obj));
} else if (typeName.equals("int")) {
value = String.valueOf(field.getInt(obj));
} else if (typeName.equals("long")) {
value = String.valueOf(field.getLong(obj));
} else if (typeName.equals("float")) {
value = String.valueOf(field.getFloat(obj));
} else if (typeName.equals("double")) {
value = String.valueOf(field.getDouble(obj));
}
} else if (typeName.equals("java.lang.String")) { // 是否为String
value = field.get(obj) == null ? "null" : field.get(obj)
.toString();
} else if (typeName.equals("[B")) { // 是否为byte[]
typeName = getTypeHelper(type); // 字符代码->[]形式
// 用Base64将byte[]转成字符串(SDK 2.2之后自带)
value = field.get(obj) == null ? "null"
: Base64.encodeToString((byte[]) field.get(obj),
Base64.DEFAULT);
} else { // 其他类型暂不需要
isWrite = false;
}
if (isWrite) {
varName = field.getName(); // 获取变量名
serializer.startTag(null, varName);
writeTag(serializer, tag_type, typeName);
writeTag(serializer, tag_value, value);
serializer.endTag(null, varName);
}
serializer.endTag(null, clsName);
* 字符代码->[]形式
private String getTypeHelper(Class<?> type) {
if (type.isArray()) {
Class<?> c = type.getComponentType();
return getTypeHelper(c) + "[]";
} else {
return type.getName();
* 写一个标签及值
private void writeTag(XmlSerializer serializer, String tag, String value)
throws IllegalArgumentException, IllegalStateException, IOException {
serializer.startTag(null, tag);
serializer.text(value);
serializer.endTag(null, tag);
}
<b>三、XML -> Object</b>
public class XmlParser {
* 分析XML将对应值赋予对象
* @param ins 输入流
public void parseXml(InputStream ins, String encoding, Object obj)
throws XmlPullParserException, IllegalArgumentException,
UnsupportedEncodingException, IllegalAccessException, IOException {
XmlPullParser parser = Xml.newPullParser(); // 创建一个Xml分析器
parser.setInput(ins, encoding); // 设置输入流及字符编码
parseXml(parser, obj); // 解析文档
ins.close(); // 关闭输入流
* 分析XML详细步骤
* @param parser Xml分析器
private void parseXml(XmlPullParser parser, Object obj)
Field field = null;
int tagDepth; // 标签深度
String tagName; // 标签名称
int eventType = parser.getEventType(); // 获取事件类型
while (true) {
if (eventType == XmlPullParser.START_DOCUMENT) {
// Log.i("START_DOCUMENT", "=START_DOCUMENT");
} else if (eventType == XmlPullParser.START_TAG) {
// Log.i("START_TAG", "=START_TAG");
tagDepth = parser.getDepth(); // 获取标签深度
tagName = parser.getName(); // 获取标签名称
if (tagDepth == 1) { // 一级标签
if (!tagName.equals(clsName)) { // 与对象名称不一致时
throw new XmlPullParserException("XML首标签名与对象名称不一致");
}
} else if (tagDepth == 2) { // 二级标签
// 判断标签名称是否符合类的某一字段名称
field = hasField(tagName, fields);
} else if (tagDepth == 3 && field != null) { // 三级标签
if (tagName.equals(tag_value)) { // 如果是value标签
setValue(obj, field, parser.nextText());
field = null;
} else if (eventType == XmlPullParser.END_TAG) {
// Log.i("END_TAG", "=END_TAG");
} else if (eventType == XmlPullParser.TEXT) {
// Log.i("TEXT", "=TEXT");
} else if (eventType == XmlPullParser.END_DOCUMENT) {
// Log.i("END_DOCUMENT", "=END_DOCUMENT");
break;
eventType = parser.next(); // 下一解析事件
* 判断标签名称是否符合类的某一字段名称
* @param tagName 标签名称
* @param fields 类字段集合
* @return 符合:Field;否则:null
private Field hasField(String tagName, Field[] fields) {
if (tagName.equals(field.getName())) {
return field;
return null;
* 给字段设值
* @param field 字段
* @param value 值
private void setValue(Object obj, Field field, String value)
throws IllegalArgumentException, IllegalAccessException,
UnsupportedEncodingException {
Class<?> type = field.getType(); // 变量类型
String typeName = type.getName(); // 类型名
field.setAccessible(true); // 设置变量可访问
if (type.isPrimitive()) { // 是否为基本类型
if (typeName.equals("boolean")) {
field.setBoolean(obj, Boolean.parseBoolean(value));
} else if (typeName.equals("char")) {
if (!value.equals("null")) {
field.setChar(obj, value.charAt(0));
} else if (typeName.equals("byte")) {
field.setByte(obj, Byte.parseByte(value));
} else if (typeName.equals("short")) {
field.setShort(obj, Short.parseShort(value));
} else if (typeName.equals("int")) {
field.setInt(obj, Integer.parseInt(value));
} else if (typeName.equals("long")) {
field.setLong(obj, Long.parseLong(value));
} else if (typeName.equals("float")) {
field.setFloat(obj, Float.parseFloat(value));
} else if (typeName.equals("double")) {
field.setDouble(obj, Double.parseDouble(value));
} else if (typeName.equals("java.lang.String")) { // 是否为String
if (!value.equals("null")) {
field.set(obj, value);
} else if (typeName.equals("[B")) { // 是否为byte[]
// 用Base64将字符串转成byte[](SDK 2.2之后自带)
field.set(obj, Base64.decode(value, Base64.DEFAULT));
} // 其他类型暂不需要
<b>四、后记</b>
<a href="http://down.51cto.com/data/2360816" target="_blank">附件:http://down.51cto.com/data/2360816</a>
本文转自winorlose2000 51CTO博客,原文链接:http://blog.51cto.com/vaero/900852,如需转载请自行联系原作者