Android解析XML数据和Json数据
2015-10-20 12:16
302 查看
本文主要参考以下三篇文章,排名不分先后(瞬间觉得高大上):
/article/4783901.html
/article/7961985.html
/article/1580244.html
很久没更blog了,今天写一写Android常见的两种数据解析—XML和Json。
下面贴一下数据源,来自 w3school。
先说PULL方式,个人觉得这种方式比较简单,符合自己写代码时的逻辑。
怎么样逻辑是不是很清晰,XML没有到结尾就一直读取,在开始的时候初始化List,然后根据标签名来获取内容。
再来说SAX方式。这种方式个人感觉麻烦了点,因为要额外定义一个handler来处理XML文件。
虽然SAX的逻辑也是十分清晰简单,和PULL类似,不过要额外定义一个类,个人表示不爽。
Json数据只有三种形式,值,对象,数组。不过通常我们遇到的数据都是嵌套型的,就是对象里面的某个属性可能又是一个对象或者数组。
怎样使用Gson解析嵌套型数据?如果是属性是一个对象,你就需要额外定义一个类来表示这个对象。如果属性是一个数组,你就需要使用一个List表示。
下面看看Json数据,来自慕课网
像上面这个Json数据首先是一个对象,对象里面有两个属性,status和data。status是一个值,data是一个数组,这个数组的元素是对象。所以我们要这样定义表示Json的类。
注意到了吗,类的名称可以随便命名,但是属性的名称一定要与Json的属性名称一致。上面我使用了List表示Json中的数组,因为数组里面的元素是一个对象,我又另外声明一个类来表示这个对象。
属性名一定要一致。接下来就是解析了,如果你使用的是原生的API来解释这段数据,你要额外写很多代码,而使用Gson只要这样:
只要两行代码,就将所有的数据封装到了你定义的类之中。使用Gson你关心的只是怎么去定义你的类,不用考虑解析和填充的问题。
因为数据源都在网上,使用了OkHttp获取数据源,关于OkHttp的用法请参考第三篇参考文章
最后给出源码地址:http://download.csdn.net/detail/u013983998/9196075
使用方法:打开Android Studio,新建一个Poroject,再File -> New ->Import Module
/article/4783901.html
/article/7961985.html
/article/1580244.html
很久没更blog了,今天写一写Android常见的两种数据解析—XML和Json。
XML数据解析
Android中经常用到两种方法来解析XML,SAX和PULL。另外还有一种DOM方式,表示没用过,这里就不介绍了,有兴趣的同学可以看看我列出的参考文章的第一篇或者自己度娘。下面贴一下数据源,来自 w3school。
<food> <name>Belgian Waffles</name> <price>$5.95</price> <description> two of our famous Belgian Waffles with plenty of real maple syrup </description> <calories>650</calories> </food>
先说PULL方式,个人觉得这种方式比较简单,符合自己写代码时的逻辑。
public class PullParser implements FoodParser { List<Food> mList = null; Food mFood = null; @Override public List<Food> parser(InputStream in) throws Exception { XmlPullParser mParser = Xml.newPullParser(); mParser.setInput(in,"UTF-8"); //取得当前标签的类型 int eventType = mParser.getEventType(); //根据标签类型判断执行的语句 while (eventType != XmlPullParser.END_DOCUMENT){ switch(eventType){ //XML文件开始 case XmlPullParser.START_DOCUMENT: mList = new ArrayList<Food>(); break; //标签开始 case XmlPullParser.START_TAG: if (mParser.getName().equals("food")){ mFood = new Food(); }else if (mParser.getName().equals("name")){ eventType = mParser.next(); mFood.setName(mParser.getText()); }else if (mParser.getName().equals("price")){ eventType = mParser.next(); mFood.setPrice(mParser.getText()); }else if (mParser.getName().equals("description")){ eventType = mParser.next(); mFood.setDescription(mParser.getText()); }else if (mParser.getName().equals("calories")){ eventType = mParser.next(); mFood.setCalories(Integer.parseInt(mParser.getText())); } break; //标签结束 case XmlPullParser.END_TAG: if (mParser.getName().equals("food")){ mList.add(mFood); mFood = null; } break; } eventType = mParser.next(); } return mList; } }
怎么样逻辑是不是很清晰,XML没有到结尾就一直读取,在开始的时候初始化List,然后根据标签名来获取内容。
再来说SAX方式。这种方式个人感觉麻烦了点,因为要额外定义一个handler来处理XML文件。
public class SaxParser implements FoodParser{ @Override public List<Food> parser(InputStream in) throws Exception{ SAXParserFactory mFactory = SAXParserFactory.newInstance(); SAXParser mParser = mFactory.newSAXParser(); MyHandler mHandler = new MyHandler(); mParser.parse(in,mHandler); return mHandler.getFoods(); } private static class MyHandler extends DefaultHandler { private List<Food> foods; private Food food; private StringBuilder builder; //返回解析后得到的Food对象集合 public List<Food> getFoods() { return foods; } //文档开始 @Override public void startDocument() throws SAXException { super.startDocument(); foods = new ArrayList<Food>(); builder = new StringBuilder(); } //元素标签开始 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); if (localName.equals("food")) { food = new Food(); } builder.setLength(0); //将字符长度设置为0 以便重新开始读取元素内的字符节点 } //解析内容 @Override public void characters(char[] ch, int start, int length) throws SAXException { super.characters(ch, start, length); builder.append(ch, start, length); //将读取的字符数组追加到builder中 } //标签结束 @Override public void endElement(String uri, String localName, String qName) throws SAXException { super.endElement(uri, localName, qName); if (localName.equals("description")) { food.setDescription(builder.toString()); } else if (localName.equals("name")) { food.setName(builder.toString()); } else if (localName.equals("price")) { food.setPrice(builder.toString()); } else if(localName.equals("calories")){ food.setCalories(Integer.parseInt(builder.toString())); } else if (localName.equals("food")) { foods.add(food); } } } }
虽然SAX的逻辑也是十分清晰简单,和PULL类似,不过要额外定义一个类,个人表示不爽。
利用Gson解析Json数据
解析Json数据在Android经常使用Gson库来实现,因为它简单方便、简单方便、简单方便,重要的事情说三遍。Json数据只有三种形式,值,对象,数组。不过通常我们遇到的数据都是嵌套型的,就是对象里面的某个属性可能又是一个对象或者数组。
怎样使用Gson解析嵌套型数据?如果是属性是一个对象,你就需要额外定义一个类来表示这个对象。如果属性是一个数组,你就需要使用一个List表示。
下面看看Json数据,来自慕课网
{"status":1, "data":[{"id":1,"name":"Tony\u8001\u5e08\u804ashell\u2014\u2014\u73af\u5883\u53d8\u91cf\u914d\u7f6e\u6587\u4ef6","picSmall":"http:\/\/img.mukewang.com\/55237dcc0001128c06000338-300-170.jpg","picBig":"http:\/\/img.mukewang.com\/55237dcc0001128c06000338.jpg","description":"\u4e3a\u4f60\u5e26\u6765shell\u4e2d\u7684\u73af\u5883\u53d8\u91cf\u914d\u7f6e\u6587\u4ef6","learner":12312}, {"id":2,"name":"\u6570\u5b66\u77e5\u8bc6\u5728CSS\u52a8\u753b\u4e2d\u7684\u5e94\u7528","picSmall":"http:\/\/img.mukewang.com\/55249cf30001ae8a06000338-300-170.jpg","picBig":"http:\/\/img.mukewang.com\/55249cf30001ae8a06000338.jpg","description":"\u6570\u5b66\u77e5\u8bc6\u4e0eCSS\u7ed3\u5408\u5b9e\u73b0\u9177\u70ab\u6548\u679c","learner":45625}]}
像上面这个Json数据首先是一个对象,对象里面有两个属性,status和data。status是一个值,data是一个数组,这个数组的元素是对象。所以我们要这样定义表示Json的类。
public class JsonDatas { int status; List<Course> data; public List<Course> getData() { return data; } public void setData(List<Course> data) { this.data = data; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } @Override public String toString() { return "JsonDatas{" + "data=" + data + ", status=" + status + '}'; } }
注意到了吗,类的名称可以随便命名,但是属性的名称一定要与Json的属性名称一致。上面我使用了List表示Json中的数组,因为数组里面的元素是一个对象,我又另外声明一个类来表示这个对象。
public class Course { private int id; private String name; private String picSmall; private String picBig; private String description; private int leaner; public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getLeaner() { return leaner; } public void setLeaner(int leaner) { this.leaner = leaner; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPicBig() { return picBig; } public void setPicBig(String picBig) { this.picBig = picBig; } public String getPicSmall() { return picSmall; } public void setPicSmall(String picSmall) { this.picSmall = picSmall; } @Override public String toString() { return "Course{" + "description='" + description + '\'' + ", id=" + id + ", name='" + name + '\'' + ", picSmall='" + picSmall + '\'' + ", picBig='" + picBig + '\'' + ", leaner=" + leaner + '}'; } }
属性名一定要一致。接下来就是解析了,如果你使用的是原生的API来解释这段数据,你要额外写很多代码,而使用Gson只要这样:
//得到整个对象 JsonDatas data = new Gson().fromJson(body, JsonDatas.class); //得到data属性的数据 final List<Course> courses = data.getData();
只要两行代码,就将所有的数据封装到了你定义的类之中。使用Gson你关心的只是怎么去定义你的类,不用考虑解析和填充的问题。
因为数据源都在网上,使用了OkHttp获取数据源,关于OkHttp的用法请参考第三篇参考文章
最后给出源码地址:http://download.csdn.net/detail/u013983998/9196075
使用方法:打开Android Studio,新建一个Poroject,再File -> New ->Import Module
相关文章推荐
- 使用NineOldAndroids 实现 Android ListView左右滑动删除效果
- android 下如何动态加载触摸屏驱动
- 【系统相册】Android 保存图片到系统相册
- Android学习之RecyclerView快速添加头部布局
- 【Makefile】如何写Android.mk(整理)
- GitHub最火的Android开源项目
- Android Studio系列教程六--Gradle多渠道打包
- android数据库支持的数据类型
- Android中Notification用法实例总结
- android使用镜像 Android sdk 和源码等
- android -- Can't create handler inside thread that has not called Looper.prepare()
- android 5.0预制APK方法,android5.0预制apk
- Android Dialog 系统样式讲解及透明背景
- Android四大基本组件介绍与生命周期
- [转]Android项目总结之社会化分享
- android adapter 中添加OnClickListener事件
- Android视频播放之边缓存边播放
- android开发游记:图片的上传下载-使用七牛云存储管理图片
- Android jni系统变量、函数、接口定义汇总
- 解决Android Studio 的 Alt 快捷键和Mac自带的Alt转换功能冲突