在Android学习中,掌握各种数据的解析至关重要,这篇博客主要介绍一下XML和JSON两种数据常用的解析方法。
1.xml数据的解析
解析XML格式的数据其实也有许多方式,我们主要介绍两种最常用的,Pull解析和SAX解析。
(1)Pull解析
这里先定义一段XML代码,并对其进行解析
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="1">
<name>鲁大大name>
<age>12</age>
</student>
<student id="2"><name>李大大/name><age>13</age></student>
<student id="3">
<name>王大大/name>
<age>14</age>
</student>
<student id="4">
<name>张大大name>
<age>13</age>
</student>
</students>
再创建一个对应XML文件的对应的实体类Student
public class Student {
private String id;
private String name;
private String age;
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 getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
最核心的,Pull解析类:
public class PullParser {
private List<Student> students;
private Student student;
public void getStudentsFromXMl(InputStream stream) throws Exception{
XmlPullParser parser=Xml.newPullParser();//获取pull解析器
parser.setInput(stream, "utf-8");//设置输入流的编码方式
int eventType=parser.getEventType();//得到第一个事件类型
while (eventType!=XmlPullParser.END_DOCUMENT) {//直到文档结束一直循环处理
if(eventType==XmlPullParser.START_DOCUMENT){//文档开始
students=new ArrayList<Student>();
}else if(eventType==XmlPullParser.START_TAG){//标签开始
String tagName=parser.getName();//获取标签名称
if(tagName!=null){
if(tagName.equals("student")){
student=new Student();
student.setId(parser.getAttributeValue(0));
}else if(tagName.equals("name")){
student.setName(parser.nextText());
}else if(tagName.equals("age")){
student.setAge(parser.nextText());
}
}
}else if(eventType==XmlPullParser.END_TAG){//标签结束
String tagName=parser.getName();
if(tagName!=null&&tagName.equals("student")){
students.add(student);
student=null;
}
}
eventType=parser.next();
// Log.e("msg", "eventType="+eventType);
}
if(students!=null){
for (int i = 0; i < students.size(); i++) {
Log.e("msg","student [id="+students.get(i).getId()+", name="+students.get(i).getName()+", age="+students.get(i).getAge()+"]");
}
}
}
}
这样就完成了一段XML数据的解析了,大家举一反三。
(2)SAX解析
Pull解析方法但不是我们唯一的选择。SAX解析也是一种特别常用的XML解析方式,虽然他的用法比Pull解析要复杂一些,但在语义方面会更加清楚。
通常情况下我们都会新建一个类继承自DefaultHandler,并重写父类的五个方法,下面就用SAX解析的方式来解析一下上面Pull解析时所用的XML数据:
定义SAX处理类:
public class SAXHandler extends DefaultHandler {
private List<Student> students;
private Student student;// 当前解析的student
private String tag;// 当前解析的标签
public void getStudents() {
if(students!=null){
for (int i = 0; i < students.size(); i++) {
Log.e("msg","student [id="+students.get(i).getId()+", name="+students.get(i).getName()+", age="+students.get(i).getAge()+"]");
}
}
}
@Override
public void startDocument() throws SAXException {
// 文档开始
// Log.e("hr", "1.startDocument 文档开始");
students = new ArrayList<Student>();
}
@Override
public void endDocument() throws SAXException {
// 文档结束
// Log.e("hr", "5.endDocument 文档结束");
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// 节点开始
// Log.e("hr", "2.标签开始");
tag = localName;
if (localName.equals("student")) {
student = new Student();
student.setId(attributes.getValue("id"));
// 或者可以通过属性下标获取 attributes.getValue(0)
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// 节点结束
// Log.e("hr", "4.标签结束");
if (localName.equals("student")) {
students.add(student);
student = null;
}
tag = null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// Log.e("hr", "3.文本数据,如果标签存在换行也会进入该方法,但是data数据为null,记得做非空判断");
String data = new String(ch, start, length);
if (data != null&&tag!=null) {
if (tag.equals("name")) {
student.setName(data);
} else if (tag.equals("age")) {
student.setAge(data);
}
}
}
}
然后在MainActivity中定义一个SAX解析方法:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
.......
主方法(){
.......
parsaXMLWithSAX(resposeData);
.......
}
private void parseXMLWithSAX(String xmlData){
try{
SAXParseFactory factory = SAXparserFactory.newInstance();
XMLReader xmlReader = factory.newSAXParse().getXMLReader();
ContentHander hander = new ContentHander();
//将ContentHandler的实例设置到XMLReader中
xmlrReader.setContentHandler(handler);
//开始执行解析
xmlReader.parse(new InputSourse(new StringReader(xmlData)));
}catch(Exception e){
e.printStackTrace();
}
}
}
这样便完成了SAX解析数据的过程。
除了Pull解析和SAX解析以外,还有一中DOM解析方式也挺常用的,我就不介绍了,留给大家可以跟我一起探索。
2.JSON解析
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。
JSON建构于两种结构:
“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。
JSON解析同样也有很多种方法,我只给大家介绍JSONObject,也可以使用GSON,其他方法就不多介绍了。
(1)JSONObject
这里创建一个JSONObject解析方法用来解析网络请求返回的JSON数据,只需要在方法中传回所需处理的JSON数据:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
........
parseJSONWithJSONObject(responseData);
}
private 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 name = jsonObject.getString("name");
String version = jsonObject.getString("Version");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
可以看到JSONObject的解析十分清晰。
(2)尽管JSONObject解析十分简单,但开源库GSON更加简单。
首先需要在项目中添加GSON的依赖库:
complie'com.google.code.gson:gson:2.7'
然后需要创建JSON数据对应的实体类,下面新增一个APP类,加入id,name,version三个字段:
public class App {
private String id;
private String name;
private String version;
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setVersion(String version) {
this.version = version;
}
}
然后修改主活动中的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
........
parseJSONWithGson(responseData);//GSON解析数据
}
private void parseJSONWithGSON(String jsonData){
GSON gson = new Gson;
Lis<App>appList = gson.fromJson(jsonData,new TypeToken<List<App>>(){}.getType);
}
}
怎么样?GSON解析对于我们是不是更加简单友好。
本篇博客对于XML和JSON的数据解析就介绍到这里,其他解析方法大家一起寻找吧!