在pull xml(1): 创建xml文件文章中主要说了说如何生成xml文件,该篇博客主要谈谈如何解析已知的xml文件。
运行界面,如下展示:
没有什么可以搪塞的,看源码吧!
1. 业务逻辑类PullXMLUtils
主要是解析或者生成xml文件
package mark.zhang;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
import android.util.Log;
import android.util.Xml;
public class PullXMLUtils {
/**
* 创建xml文件
*
* @param items
* 存储view状态
* @param outStream
* 输出
* @throws Exception
*/
public static void createXML(List<ViewState> items, OutputStream outStream)
throws Exception {
XmlSerializer serializer = Xml.newSerializer();
// 设置输出及编码
serializer.setOutput(outStream, "utf-8");
// 构建文档类似:<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
serializer.startDocument("utf-8", true);
// 开始Tag
serializer.startTag(null, "state");
for (ViewState vs : items) { // 增强for循环
serializer.startTag(null, "view");
serializer.attribute(null, "name", vs.getName());
serializer.startTag(null, "text");
serializer.text(vs.getText());
serializer.endTag(null, "text");
serializer.startTag(null, "id");
serializer.text(String.valueOf(vs.getId()));
serializer.endTag(null, "id");
serializer.endTag(null, "view");
}
// 结束Tag
serializer.endTag(null, "state");
// 结束文档
serializer.endDocument();
// 关闭流
outStream.flush();
outStream.close();
}
/**
* 创建xml文件,过载方法
*
* @param items
* 存储view状态
* @param writer
* 字符流
* @throws Exception
*/
public static void createXML(List<ViewState> items, Writer writer)
throws Exception {
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(writer);
serializer.startDocument("utf-8", true);
serializer.startTag(null, "state");
for (ViewState vs : items) {
serializer.startTag(null, "view");
serializer.attribute(null, "name", vs.getName());
serializer.startTag(null, "text");
serializer.text(vs.getText());
serializer.endTag(null, "text");
serializer.startTag(null, "id");
serializer.text(String.valueOf(vs.getId()));
serializer.endTag(null, "id");
serializer.endTag(null, "view");
}
serializer.endTag(null, "state");
serializer.endDocument();
// 关闭流
writer.flush();
writer.close();
}
/**
* 解析xml文件
*
* @param inputStream
* 输入流
*
* @throws XmlPullParserException
* @throws IOException
* @return 集合对象ArrayList
*/
public static ArrayList<ViewState> parseXML(InputStream inputStream)
throws XmlPullParserException, IOException {
ViewState vState = null;
ArrayList<ViewState> items = null;
XmlPullParser parser = Xml.newPullParser();
parser.setInput(inputStream, "utf-8");
// 事件驱动类型码
// XmlPullParser.START_DOCUMENT = 0
// XmlPullParser.END_DOCUMENT = 1
// XmlPullParser.START_TAG = 2
// XmlPullParser.END_TAG = 3
// XmlPullParser.TEXT = 4
int eventType = parser.getEventType();
/* 不是结束文档的话,一直循环 */
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
// 文档开始(<?xml version='1.0' encoding='utf-8' standalone='yes'?>)
// 初始化逻辑代码可以放在这里
items = new ArrayList<ViewState>();
break;
case XmlPullParser.START_TAG:
// 文档开始节点
if ("view".equals(parser.getName())) {
Log.d("mark", "num: " + parser.getAttributeCount());
// 获得属性值的个数
int count = parser.getAttributeCount();
// 索引从0开始,这里只有一个name属性值,所以下面代码等效
// String name = parser.getAttributeValue(0);
String name = parser.getAttributeValue(count-1);
vState = new ViewState();
vState.setName(name);
}
if (vState != null) {
if ("text".equals(parser.getName())) {
vState.setText(parser.nextText());
}
if ("id".equals(parser.getName())) {
vState.setId(new Integer(parser.nextText()));
}
}
break;
case XmlPullParser.TEXT:
// 如果是文本
break;
case XmlPullParser.END_TAG:
// 文档结束节点
if ("view".equals(parser.getName())) {
items.add(vState);
vState = null;
}
break;
}
// 获得下一个事件类型
eventType = parser.next();
}
return items;
}
}
2. Activity
MasterActivity类。
package mark.zhang;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MasterActivity extends Activity {
private Button btn_createXML = null;
private Button btn_parseXML = null;
private ListenerEven listenerEven = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
findViews();
setEvens();
}
/**
* 初始化
*
*/
private void init() {
System.out.println(getPackageName());// mark.zhang
listenerEven = new ListenerEven();
}
/**
* 设置监听
*
*/
private void setEvens() {
btn_createXML.setOnClickListener(listenerEven);
btn_parseXML.setOnClickListener(listenerEven);
}
/**
* 创建控件对象
*/
private void findViews() {
btn_createXML = (Button) findViewById(R.id.btn_createXML);
btn_parseXML = (Button) findViewById(R.id.btn_parseXML);
}
/**
* 创建xml文件
* @throws Exception
*/
public void createXML() throws Exception {
// 创建文件保存路径:data/data/app/files/uistate.xml
System.out.println("getFilesDir(): " + getFilesDir().getAbsolutePath());
System.out.println("getFilesDir(): " + getFilesDir().getName());
File file = new File(getFilesDir(), "uistate.xml");
ArrayList<ViewState> vState = new ArrayList<ViewState>();
// 添加数据
vState.add(new ViewState("button", "send", 10));
vState.add(new ViewState("textview", "this is a demo!", 11));
// 方式1
/*FileOutputStream outStream = new FileOutputStream(file);
PullXMLUtils.createXML(vState, outStream);*/
// 方式2
FileWriter writer = new FileWriter(file);
PullXMLUtils.createXML(vState, writer);
// 方式3:可用于显示
/*StringWriter sWriter = new StringWriter();
Log.d("mark", sWriter.toString());*/
}
/**
* 解析xml文件,该文件来自data/data/App包名/files目录
*
* @throws XmlPullParserException
* @throws IOException
*/
public void parseXML() throws XmlPullParserException, IOException {
FileInputStream inStream = openFileInput("uistate.xml");
ArrayList<ViewState> items = PullXMLUtils.parseXML(inStream);
for(ViewState vState : items) {
Log.d("mark", vState.toString());
}
}
/**
* 解析来自资源文件的xml文件,一般将文件放到工程目录/src下面
*
* @throws XmlPullParserException
* @throws IOException
*/
public void parseFormResourceXML() throws XmlPullParserException, IOException{
InputStream inStream = this.getClass().getClassLoader().getResourceAsStream("uistate.xml");
ArrayList<ViewState> items = PullXMLUtils.parseXML(inStream);
for(ViewState vState : items) {
Log.d("mark", vState.toString());
}
}
/**
* @author mark
*
* 内部类,Button点击事件处理
*/
final class ListenerEven implements OnClickListener {
@Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.btn_createXML:
try {
createXML();
} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.btn_parseXML:
try {
//parseXML();
parseFormResourceXML();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
}
3. 说明
如果使用parseXML()方法解析xml文件的话,需要先createXML(),这样在对应文件夹下面才会产生xml文件。
如果使用parseFormResourceXML()方法解析xml文件的话,需要准备xml文件,对应目录如下:
即把uistate.xml文件放到src目录下面。
4. uistate.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<state>
<view name="button">
<text>send</text>
<id>10</id>
</view>
<view name="textview">
<text>this is a demo!</text>
<id>11</id>
</view>
</state>