解析XML 格式数据
解析XML格式数据其实有很多种方式,比较常用的两种就是 Pull解析和SAX解析。
Pull 解析方式
xml数据:
String xmlData = "<apps>"
+"<app><id>1</id><name>Google Maps</name><version>1.0</version></app>"
+"<app><id>2</id><name>Chrome</name><version>2.1</version>"
+"<app><id>3</id><name>Google Play</name><version>2.3</version></app>"
+ "</apps>";
解析:
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();
xmlPullParser.setInput(new StringReader(xmlData));
int eventType = xmlPullParser.getEventType();
String id = "";
String name = "";
String version = "";
//遍历所有节点
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.e("mylog", "id is "+id);
Log.e("mylog", "name is "+name);
Log.e("mylog", "version is "+version);
}
break;
default:
break;
}
eventType = xmlPullParser.next();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SAX 解析方式
Pull 解析方法虽然比较好用,但它并不是我们唯一的选择。SAX解析也是一种非常常用的解析方式,虽然它的解析方法比Pull解析要复杂一些,但在语义上更加清楚。
通常情况下,我们都会新建一个类继承自DefaultHandler,并重写父类的5个方法:
public class MyHandler extends DefaultHandler{
private String nodeName;
private StringBuilder id;
private StringBuilder name;
private StringBuilder version;
@Override
public void startDocument() throws SAXException {
// 开始解析的时候调用
super.startDocument();
id = new StringBuilder();
name = new StringBuilder();
version = new StringBuilder();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// 开始解析某个节点的时候调用
super.startElement(uri, localName, qName, attributes);
//记录当前节点名
nodeName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// 获取节点内容时调用,可能会被调用多次
//一些换行符也被当做内容解析出来,我们需要针对这种情况在代码中做好控制
super.characters(ch, start, length);
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);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// 完成解析某个节点时调用
super.endElement(uri, localName, qName);
if("app".equals(localName)) {
Log.e("mylog", "id is "+id.toString().trim());
Log.e("mylog", " name is "+name.toString().trim());
Log.e("mylog", "version is "+version.toString().trim());
//最后要将StringBuilder 清空
id.setLength(0);
name.setLength(0);
version.setLength(0);
}
}
@Override
public void endDocument() throws SAXException {
// 完成整个XML解析的时候调用
super.endDocument();
}
}
然后开始解析:
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
XMLReader reader = factory.newSAXParser().getXMLReader();
MyHandler handler = new MyHandler();
//将 MyHandler 的实例设置到XMLReader中
reader.setContentHandler(handler);
//开始执行解析
reader.parse(new InputSource(new StringReader(xmlData)));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
解析JSON格式数据
使用JSONObject
解析JSON数据也有很多种方法,可是使用官方提供的JSONObject,也可以使用谷歌开源库GSON。另外,一些第三方开源库如 Jackson,FastSON 等也非常不错。
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"}
]
使用JSONObject:
public void parseJSONWithJSONObject(String jsonData){
try{
JSONArray jsonArray = new JSONArray(jsonData);
for(int i =0;i<jsonArray.length();i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
String id = jsonObject.getString("id");
String version = jsonObject.getString("version");
String name = jsonObject.getString("name");
Log.e("mylog","id is "+id);
Log.e("mylog","version is "+version);
Log.e("mylog","name is "+name);
}
}catch(Exception e){
e.printStackTrace();
}
}
使用GSON
如果你认为使用JSONObject 来解析JSON数据已经非常简单了,那你就太年轻了。谷歌提供的GSON开源库可以让解析JSON数据的工作简单到让你不敢想象的地步。不过GSON并没有添加的Android官方的API中,因此想要使用这个功能的话,就必须要在项目中添加GSON库的依赖。
GSON主要可以将一段JSON格式的字符串自动映射成一个对象,从而不需要我们再手动去编写代码进行解析了。
比如说一段JSON格式的数据如下所示:
{"name":"Tom", "age":20}
那我们就可以定义一个Person类,并加入name和age两个字段,然后只需简单地调用如下代码就可以将JSON数据自动解析成一个Person对象了:
Gson gson = new Gson();
Person person = gson.fromJson(jsonData Person.class);
如果需要解析一段JSON数组就会稍微麻烦一点,我们需要借助TypeToken将期望解析成的数据类型传入到fromJson()方法中,如下所示:
List<Person> people = gson.fromJson(JsonData, new TypeToken<List<Person>>(){}.getType());
现在来尝试解析下面的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"}
]
先创建一个APP类:
public class APP{
private String id;
private String name;
private String version;
....... (getter 和 setter)
}
然后解析:
public void parseJSONWithGSON(String jsonData){
Gson gson = new Gson();
List<APP> applist = gson.fromJson(jsonData, new TypeToken<List<APP>>(){}.getType());
for(App app:applist){
Log.e("mylog","id is "+app.getId());
Log.e("mylog","name is "+app.getName());
Log.e("mylog","version "+app.getVersion());
}
}