1.XML格式数据解析
XML格式数据:
<apps>
<app>
<id>1</id>
<name>Google Maps</name>
<version>1.0</version>
</app>
<app>...</app>
</apps>
- Pull解析:
首先,利用工厂方法获得XmlPullParser实例对象。
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
接下来,将服务器返回的数据传入,获得XML数据的相关信息(eventType)。
//设置输入流
xmlPullParser.setInput(new StringReader(xmlData));
//获得当前的解析事件
int eventType = xmlPullParser.getEventType();
根据当前解析事件的类型进行循环读取、解析。
while(eventType != XmlPullParser.END_DOCUMENT) {
String nodeName = xmlPullParser.getName();
switch(eventType) {
//开始解析节点
case XmlPullParser.START_TAG: {
if("id".equals(nodeName)) {
id = xmlPullParser.nextText();
} else if ("name".equals(nodeName)) {
name = xmlPullParser.nextText();
} else if ("version".equals(nodeName)) {
version = xmlPullParser.nextText();
}
break;
}
//完成解析某个节点
case XmlPullParser.END_TAG:{
if ("app".equals(nodeName)) {
//输出信息
Log.d("MainActivity","id is " + id);
Log.d("MainActivity","name is " + name);
Log.d("MainActivity","version is " + version);
}
break;
}
default :
break;
}
//获取下一个解析事件
eventType = xmlPullParser.next();
}
-
SAX解析
首先,新建一个类继承自DefaulfHandler,并重写父类的5个方法。
每当开始解析某个节点的时候,startElement()方法就会得到调用,其中localName参数记录着当前节点的名字。
接着在解析节点中具体内容的时候就会调用characters()方法,根据当前节点名(在startElement()方法中获得)进行判断,将解析出的内容添加到对应的StringBuilder对象中。
最后在endElement()方法中进行判断,如果app节点已经解析完成,就打印出id、name和version的内容,并清空StringBuilder。
public class MyHandler extends DefaultHandler {
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
/**
* 在开始XML解析时调用
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
/**
* 在完成整个XML解析时调用
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
}
/**
* 在开始解析某个节点时调用
* @param uri
* @param localName
* @param qName
* @param attributes
* @throws SAXException
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
//记录当前节点名
nodeName = localName;
}
/**
* 在完成解析某个节点时调用
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("app".equals(localName)) {
Log.d("MyHandler", "id is " + id.toString().trim());
Log.d("MyHandler", "name is " + name.toString().trim());
Log.d("MyHandler", "version is " + version.toString().trim());
//将StringBuilder清空
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
/**
* 获取节点中间内容的时候调用
* @param ch
* @param start
* @param length
* @throws SAXException
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//根据当前的节点名判断将内容添加到哪一个StringBuilder对象中
if ("id".equals(nodeName)) {
id.append(ch, start, length);
} else if ("name".equals(nodeName)) {
name.append(ch, start, length);
} else if ("version".equals(nodeName)) {
version.append(ch, start, length);
}
}
}
父类的方法重写完毕后,调用工厂方法,构建XMLReader的实例对象,将MyHandler的实例设置到XMLReader中。
SAXParserFactory factory = SAXParserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
MyHandler myHandler = new MyHandler();
//将MyHandler的实例设置到XMLReader中
xmlReader.setContentHandler(myHandler);
//构建输入流,开始解析,数据在MyHandler中进行处理
xmlReader.parse(new InputSource(new StringReader(xmlData)));
2.JSON格式数据解析
JSON具有体积小的优势,在数据传输中会经常被使用。
JSON格式:
[{"id":"5","version":"5.5","name":"Clash of Clans"},
{"id":"6","version":"7.0","name":"Boom Beach"},
{"id":"7","version":"3.5","name":"Clash Royale"}]
解析JSON数据的方法有很多种,这里主要介绍JSONObject和GSON。
- JSONObject
在介绍JSONObject之前,需要介绍一个JSONArray的概念。以上面的JSON格式的数据为例,"{ }"内的信息为一个JSONObject,"[ ]"内的信息是由3个JSONObject组成的一个JSONArray。
当返回的数据格式是JSONArray时,循环遍历这个JSONArray,从中取出的每一个元素都是一个JSONObject对象,每个JSONObject对象中包含所需要的信息。
//当返回信息的格式为JSONArray
JSONArray jsonArray = new JSONArray(jsonData);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
}
//当返回信息格式为JSONObject
JSONObject jsonObject = new JSONObject(jsonData);
String id = jsonObject.getString("id");
String name = jsonObject.getString("name");
String version = jsonObject.getString("version");
-
GSON
使用GSON从服务器获取数据,需要建立相应的JavaBean,形成相应的映射。
public class App {
//JavaBean的属性名称需要与想要获取的JSON格式中的数据名称保持一致
private String id;//"id"
private String name;
private String version;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
当返回的数据是JSONObject时:
Gson gson = new Gson();
App app = gson.fromJson(jsonData, App.class);
当返回的数据是JSONArray时,需要借助TypeToken类(需要匿名类来调构造函数)将期望解析成的数据类型传入fromJson()方法中:
Gson gson = new Gson();
List<App> appList = gson.fromJson(jsonData,
//利用TypeToken的匿名类来构建实例
new TypeToken<List<App>>(){ }.getType());
for(App app : appList) {
Log.d("TAG", "id is " + app.getId());
Log.d("TAG", "name is " + app.getName());
Log.d("TAG", "version is " + app.getVersion());
}