XML是可扩展标记语言,JSON是轻量级的数据交换格式,它们两者在各种程序中都会出现,其中json的出现频率十分惊人。很多人可能不清楚它们的作用原理,甚至连简单使用都不清楚,今天看到一位大佬的文章,对安卓中的XML和JSON的用法所得很是清楚,并且对这xml语言和json数据进行了比较直观的对比。这两种用来存储数据的…姑且叫语言吧,不知道怎么说了,如何使用,请看下面解析内容。
XML
概述
XML是一种常用的存储数据方式,设计初衷就是为了传输和存储数据。
在Android平台中内部很多地方使用了XML存储:
- 比如之前的SharedPreferences的存储就是使用了XML文件,持久化存储的同时又兼具轻量的特性。
XML解析主要有三种方式:
- SAX(Simple API for XML)
- DOM(Document Object Model)
- Android附带的PULL解析器解析XML文件
它们对应的特点如下:
- 一些性能敏感的数据库或手机上主要采用SAX方式,SAX读取是单向的,优点是不占内存空间、解析属性方便,但缺点就是对于套嵌多个分支来说处理不是很方便。
- 常规在PC上开发我们使用Dom更为轻松一些,DOM方式会把整个XML文件加载到内存中去,优点是可以任意读取节点,但缺点就是会消耗内存。
- PULL常常用在移动设备对于节点处理比较好,也比较节省内存。Pull解析器的运行方式与SAX解析器相似,它提供了类似的事件,如:
parser.next() //开始元素和结束元素事件,可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。 parser.nextTextl() //当元素开始解析时,调用该方法可以获取下一个Text类型元素的值。
PULL解析器解析XML文件
可用按照下面的步骤解析XML文件
-
- android给我们提供了xml用来得到xmlpull解析器
复制
XmlPullParser parser =Xml.newPullParser()
- 传入文件输入流及xml文件编码
复制
parser.setinput(in, "UTF.8);
- pull读到xml后返回EventType,EventType有如下五种
- START DOCUMENT——读取到xml的声明返回数字0
- END DOCUMENT——读取到xml的结束返回数字1
- START TAG——读取到xml的开始标签返回数字2
- END TAG——读取到xml的结束标签返回数字3
- TEXT——读取到xml的文本返回数字4
- 获取当前EventType
复制
int eventType = parser.getEventType()
- 获取下一下事件类型
复制
while(eventType!-XmlPullParser.END DOCUMENT){ switch (eventTypel) {...} eventType- parser.next(); }
- android给我们提供了xml用来得到xmlpull解析器
DEMO
在开始之前,先学习一下怎么写一个简单的XML文件。
package com.example.a4_10xml; public class Classmate { int sno; String name; String sex; int age; @Override public String toString() { return "Classmate{" + "sno=" + sno + ", name='" + name + '\'' + ", sex='" + sex + '\'' + ", age=" + age + ", grade=" + grade + '}'; } int grade; }
我们把写好的xml文件放在res/raw目录下(原生目录)
对xml文件准备一个类
package com.example.a4_10xml; public class Classmate { int sno; String name; String sex; int age; int grade; }
准备一个Button
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/xmlpull" android:onClick="xmlpull" android:text="PULL解析器解析XML文件" app:layout_constraintTop_toTopOf="parent"/>
package com.example.a4_10xml; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Xml; import android.view.View; import android.widget.ArrayAdapter; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //使用PULL解析XML文件 (点击事件) public void xmlpull(View v){ ArrayList<Classmate> list = parser(); for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } private ArrayList<Classmate> parser(){ //创建ArrayList ArrayList<Classmate> list = new ArrayList<>(); Classmate classmate = null; //创建PULL解析器 XmlPullParser pullParser = Xml.newPullParser(); //StringReader stringReader = new StringReader(xml); InputStream in = getResources().openRawResource(R.raw.test); try { //设置要解析的文件流 pullParser.setInput(in,"UTF-8"); //获取当前的事件类型 int eventType = pullParser.getEventType(); //不等于文档解析结束 while (eventType!=XmlPullParser.END_DOCUMENT){ switch (eventType){ //开始标记 case XmlPullParser.START_TAG: String tag = pullParser.getName(); if ("classmate".equals(tag)){ classmate = new Classmate(); classmate.sno = Integer.parseInt(pullParser.getAttributeValue(null,"sno")); } else if("name".equals(tag)){ classmate.name = pullParser.nextText(); } else if("sex".equals(tag)){ classmate.sex = pullParser.nextText(); } else if("name".equals(tag)){ classmate.age = Integer.parseInt(pullParser.nextText()); } else if("name".equals(tag)){ classmate.grade = Integer.parseInt(pullParser.nextText()); } break; //结束标记 case XmlPullParser.END_TAG: if("classmate".equals(pullParser.getName())){ //添加到list list.add(classmate); } break; } //获取下一个事件类型,开始循环 eventType = pullParser.next(); } } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return list; } }
效果如下:
JSON
概述
- JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
- 它基于JavaScript(Standard ECMA-262 3rd Edition – December 1999)的一个子集。
- JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。
- 这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
JSON数据格式特点
JSON建构于两种结构:
- “名称/值”对的集合
- 值的有序列表(数组)
JSON表示名称/值对的方式:
JSON 对象
JSON 对象在花括号中书写:
对象可以包含多个名称/值对:
{ "firstName":"John" , "lastName":"Doe" }
这一点也容易理解,与这条 JavaScript 语句等价:
firstName = "John" lastName = "Doe"
JSON 数组
JSON 数组在方括号中书写:
数组可包含多个对象:
{ "employees": [ { "firstName":"John" , "lastName":"Doe" }, { "firstName":"Anna" , "lastName":"Smith" }, { "firstName":"Peter" , "lastName":"Jones" } ] }
JSONReader
JSONReader是android.util包下的一个用于解析JSON的工具类。
注意:最低版本要求是API 11。
使用方式:
JsonReader reader = new JsonReader(new StringReaderljsonDatal)
使用JsonReader解析JSON数据,类似的准备一个json文件
{ "user":[ {"name":"中国移动","tel":10086,"Resume":"测试1"},{"name":"中国电信","tel":10000,"Resume":"测试1"} ] }
类似的也需要准备一个对应的类,方便起见全string了….
package com.example.a4_10json; public class Person { String name; String tel; String Resume; @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", tel='" + tel + '\'' + ", Resume='" + Resume + '\'' + '}'; } }
完整代码如下:
package com.example.a4_10json; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.JsonReader; import android.view.View; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void json_read(View v){ ArrayList<Person> list= jsonReader(); for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } private ArrayList<Person> jsonReader() { ArrayList<Person> list=new ArrayList<>(); Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test)); JsonReader jr=new JsonReader(r); try { //开始解析对象 jr.beginObject(); if (jr.hasNext()) { if ("user".equals(jr.nextName())) { //开始解析数组 jr.beginArray(); //解析每一个对象 while (jr.hasNext()){ //开始解析对象 Person p = new Person(); jr.beginObject(); while (jr.hasNext()){ //得到属性名称 String name = jr.nextName(); if("name".equals(name)){ //得到姓名 p.name=jr.nextString(); }else if("tel".equals(name)){ //电话 p.tel=jr.nextString(); }else if("Resume".equals(name)){ //简介 p.Resume=jr.nextString(); } } //结束对象的解析 jr.endObject(); //添加到list list.add(p); } //结束数组解析 jr.endArray(); } } //结束对象解析 jr.endObject(); } catch (IOException e) { e.printStackTrace(); } return list; } }
效果如下:
生成一组JSON数据
下面提供一段完整的Demo
准备一个Butoon
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/json_create" android:onClick="json_create" android:text="生成一组JSON数据" app:layout_constraintTop_toBottomOf="@id/json_read"/>
使用JsonReader解析JSON数据注释往下的部分为上一个Demo的代码
package com.example.a4_10json; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.JsonReader; import android.view.View; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //生成一组JSON数据 public void json_create(View v){ ArrayList<Person> list=new ArrayList<>(); Person p1=new Person(); p1.name="生成的数据1"; p1.tel="123"; p1.Resume="测试1"; Person p2=new Person(); p2.name="生成的数据1"; p2.tel="456"; p2.Resume="测试2"; //添加 list.add(p1); list.add(p2); JSONObject json=new JSONObject(); JSONArray array=new JSONArray(); try { for (int i=0;i<list.size();i++){ Person p=list.get(i); JSONObject obj=new JSONObject(); obj.put("name",p.name); obj.put("tel",p.tel); obj.put("Resume",p.Resume); array.put(obj); } json.put("person",array); } catch (JSONException e) { e.printStackTrace(); } System.out.println(json.toString()); } //使用JsonReader解析JSON数据 public void json_read(View v){ ArrayList<Person> list= jsonReader(); for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } private ArrayList<Person> jsonReader() { ArrayList<Person> list=new ArrayList<>(); Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test)); JsonReader jr=new JsonReader(r); try { //开始解析对象 jr.beginObject(); if (jr.hasNext()) { if ("user".equals(jr.nextName())) { //开始解析数组 jr.beginArray(); //解析每一个对象 while (jr.hasNext()){ //开始解析对象 Person p = new Person(); jr.beginObject(); while (jr.hasNext()){ //得到属性名称 String name = jr.nextName(); if("name".equals(name)){ //得到姓名 p.name=jr.nextString(); }else if("tel".equals(name)){ //电话 p.tel=jr.nextString(); }else if("Resume".equals(name)){ //简介 p.Resume=jr.nextString(); } } //结束对象的解析 jr.endObject(); //添加到list list.add(p); } //结束数组解析 jr.endArray(); } } //结束对象解析 jr.endObject(); } catch (IOException e) { e.printStackTrace(); } return list; } }
效果如下:
GSON
概述
GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。
GITHUB地址:https://github.com/google/gson
方法
使用Gson直接把JSON数据转换成Java对象
public Student parserJSON2(String data){ Gson gson = new Gson(); Student s = gson.fromJson(data, Student.class); return s; }
使用Gson直接把JSON数组转换成Java对象
public List Student> parserJSON3(String data){ Type type = new TypeToken<ArrayList <Student>>(){}.getType(); Gson gson = new Gson(); List<Student> list =gson.fromJson(data, type); return list; }
使用GSON解析和生成JSON,使用GSON前需要导入JAR包,JAR包可以在上面提供的GITHUB地址上下载,导包这里也不多少了,基本技能。
小改一下test.js的on代码 重新建个test2.json
[{"name":"中国移动","tel":10086,"Resume":"测试1"},{"name":"中国电信","tel":10000,"Resume":"测试1"}]
最终代码:
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/GSON" android:onClick="GSON" android:text="使用GSON解析JSON" app:layout_constraintTop_toBottomOf="@id/json_read"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/GSON_Create" android:onClick="GSON_Create" android:text="使用GSON生成JSON" app:layout_constraintTop_toBottomOf="@id/GSON"/>
package com.example.a4_10json; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.JsonReader; import android.view.View; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; import java.lang.reflect.Type; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //使用GSON解析JSON public void GSON(View v){ Gson gson=new Gson(); Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test2)); //选Reflect包下的Type Type type=new TypeToken<ArrayList<Person>>(){}.getType(); ArrayList<Person> list= gson.fromJson(r,type); for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } //使用GSON生成JSON public void GSON_Create(View v){ ArrayList<Person> list=new ArrayList<>(); Person p1=new Person(); p1.name="测试数据1"; p1.tel="123456"; p1.Resume="使用GSON生成JSON的数据1"; Person p2=new Person(); p2.name="测试数据2"; p2.tel="456789"; p2.Resume="使用GSON生成JSON的数据2"; list.add(p1); list.add(p2); Gson gson=new Gson(); Type type=new TypeToken<ArrayList<Person>>(){}.getType(); String json= gson.toJson(list,type); System.out.println(json); } //生成一组JSON数据 public void json_create(View v){ ArrayList<Person> list=new ArrayList<>(); Person p1=new Person(); p1.name="生成的数据1"; p1.tel="123"; p1.Resume="测试1"; Person p2=new Person(); p2.name="生成的数据1"; p2.tel="456"; p2.Resume="测试2"; //添加 list.add(p1); list.add(p2); JSONObject json=new JSONObject(); JSONArray array=new JSONArray(); try { for (int i=0;i<list.size();i++){ Person p=list.get(i); JSONObject obj=new JSONObject(); obj.put("name",p.name); obj.put("tel",p.tel); obj.put("Resume",p.Resume); array.put(obj); } json.put("person",array); } catch (JSONException e) { e.printStackTrace(); } System.out.println(json.toString()); } //使用JsonReader解析JSON数据 public void json_read(View v){ ArrayList<Person> list= jsonReader(); for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); } } private ArrayList<Person> jsonReader() { ArrayList<Person> list=new ArrayList<>(); Reader r=new InputStreamReader(getResources().openRawResource(R.raw.test)); JsonReader jr=new JsonReader(r); try { //开始解析对象 jr.beginObject(); if (jr.hasNext()) { if ("user".equals(jr.nextName())) { //开始解析数组 jr.beginArray(); //解析每一个对象 while (jr.hasNext()){ //开始解析对象 Person p = new Person(); jr.beginObject(); while (jr.hasNext()){ //得到属性名称 String name = jr.nextName(); if("name".equals(name)){ //得到姓名 p.name=jr.nextString(); }else if("tel".equals(name)){ //电话 p.tel=jr.nextString(); }else if("Resume".equals(name)){ //简介 p.Resume=jr.nextString(); } } //结束对象的解析 jr.endObject(); //添加到list list.add(p); } //结束数组解析 jr.endArray(); } } //结束对象解析 jr.endObject(); } catch (IOException e) { e.printStackTrace(); } return list; } }
效果如下:
XML和JSON的对比
从以下6点比较JSON与XML :
- JSON和XML的数据可读性基本相同
- JSON和XML同样拥有丰富的解析手段
- JSON相对于XML来讲,数据的体积小
- JSON与JavaScript的交互更加方便
- JSON对数据的描述性比XML较差
- JSON的速度要远远快于XML
评论 (0)