AndroidStudio-3.2.1(十五)JSON和XML基本操作

  • Post author:
  • Post category:其他


本篇介绍json数据的读写和xml数据的序列化。

JSON和XML是目前常用的数据交换格式,相比而言,JSON更轻量,是目前BS架构里主流的数据交换格式;XML则常用作配置文件。

下面通过示例演示两种格式的常用读写方法,先做好前戏,比如新建一个Student类:

    public class Student {
        public Student() {
        }

        public Student(String name, Integer age, Date birthday) {
            Name = name;
            Age = age;
            Birthday = birthday;
        }
        public String Name;
        public Integer Age;
        public Date Birthday;
        @NonNull
        @Override
        public String toString() {
            return String.format("Name:%s   Age:%d   Birthday:%s",Name,Age,Birthday);
        }
    }



JSON读写

JSON读写主要用到两个类JSONObject和JSONArray:

  • JSONObject:JSON对象,用{}来界定一个JSON对象;
  • JSONArray:JSON数组,用[]来界定一个JSON数组;
  • 上述两个类型可互相嵌套


构建JSON对象

假设1个班级有4个学生,现在要构建这个班级对象。

 private void Export2JSON() {
        try {
            JSONObject root = new JSONObject();
            root.put("class", "三年二班");
            JSONArray jsonArray = new JSONArray();
            for (int i = 0; i < studentList.size(); i++) {
                JSONObject stu = new JSONObject();
                stu.put("name", studentList.get(i).Name);
                stu.put("age", studentList.get(i).Age);
                stu.put("birthday", studentList.get(i).Birthday.toLocaleString());
                jsonArray.put(stu);
            }
            root.put("students", jsonArray);
            System.out.println(root.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

代码没什么难理解的,最后构建好的json对象如下:

{
  "class":"三年二班",
  "students":[
        {"birthday":"1987/10/12","age":25,"name":"八神"},
        {"birthday":"1998/11/4","age":25,"name":"草薙"},
        {"birthday":"1990/3/18","age":22,"name":"K'"},
        {"birthday":"1992/7/8,","age":20,"name":"ASH"}]
}


读取JSON数据

我们在asset文件夹中创建一个students.json文件,并将刚才的json对象拷贝进去。

 private void ReadJSON() {
        try {
            //读取文件到字符串中
            InputStreamReader isr = new InputStreamReader(getAssets().open("students.json"), "UTF-8");
            BufferedReader bufferedReader = new BufferedReader(isr);
            String line;
            StringBuilder builder = new StringBuilder();
            while ((line = bufferedReader.readLine()) != null) {
                builder.append(line);
            }
            //从字符串中解析JSON对象
            JSONObject jsonObject = new JSONObject(builder.toString());
            System.out.println("class:" + jsonObject.getString("class"));
            JSONArray jsonArray = jsonObject.getJSONArray("students");
            for (int i = 0; i < jsonArray.length(); i++) {
                System.out.println("学生" + i);
                System.out.println(jsonArray.getJSONObject(i).getString("name"));
                System.out.println(jsonArray.getJSONObject(i).getInt("age"));
                System.out.println(jsonArray.getJSONObject(i).getString("birthday"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

可以直接从字符串解析到JSON。注意的是,要判断字符串代表的是JSONObject还是JSONArray,再使用对应的类型去解析。



XML读写

对XML的读写有两种方式,利用DocumentBuilder和序列化,这里介绍序列化的方式。



构建xml文件

将4个学生的信息构建成xml文件,存储到程序路径下:

private void Export2XML() {
        try {
            XmlSerializer serializer = Xml.newSerializer();
            FileOutputStream fos = openFileOutput("students.xml", MODE_PRIVATE);        //获取输入流
            serializer.setOutput(fos, "utf-8");//设置输入流和编码
            // 开始文档
            serializer.startDocument("utf-8", true);
            serializer.startTag(null, "students");
            // 循环写入对象
            for (int i = 0; i < studentList.size(); i++) {
                serializer.startTag(null, "student");
                serializer.attribute("", "name", studentList.get(i).Name);
                serializer.attribute("", "age", studentList.get(i).Age.toString());
                serializer.startTag(null, "birthday");
                serializer.text(studentList.get(i).Birthday.toLocaleString());
                serializer.endTag(null, "birthday");
                serializer.endTag(null, "student");
            }
            serializer.endTag(null, "students");
            serializer.endDocument();// 结束文档
            System.out.println("序列化完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

主要用到XmlSerializer 类,方法如下:

  • startDocument/endDocument 开始/结束一个xml文档
  • startTag/endTag 开始/结束一个xml节点
  • attribute 在当前标签加入属性
  • text 给当前标签设置值

    上面代码构建出的xml文件形式如下:
<?xml version="1.0" encoding="utf-8"?>
<students>
  <student name="八神" age="25">
    <birthday>Nov 12, 3887 12:00:00 AM</birthday>
  </student>
  ...
</students>


序列化xml文件

使用XmlPullParser,工作原理是通过getEventType方法逐

标签

的遍历xml文件,并取出其中的text和attrbute。

我们将刚才构建的xml文件序列化到实体类中:

    private void ReadXML() {
        try {
            XmlPullParser parser = Xml.newPullParser();
            FileInputStream fis = openFileInput("students.xml");
            parser.setInput(fis, "utf-8");
            int eventType = parser.getEventType();
            List<Student> list = null;
            Student stu = null;
            while (eventType != XmlPullParser.END_DOCUMENT) {
                switch (eventType) {
                    case XmlPullParser.START_TAG:
                        if (parser.getName().equals("students")) { //读到根标签,创建数组
                            list = new ArrayList<Student>();
                        } else if (parser.getName().equals("student")) {  //读到student说明要开始创建对象
                            stu = new Student();
                            //设置对象的属性
                            stu.Name = parser.getAttributeValue("", "name");
                            stu.Age = Integer.parseInt(parser.getAttributeValue("", "age"));
                        } else if (parser.getName().equals("birthday")) {
                            stu.Birthday = new Date(Date.parse(parser.nextText()));//nextText调用后parser会指到EndTag
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        //读到student,说明一个对象对去完毕添加到list集合中,重置stu
                        if (parser.getName().equals("student")) {
                            list.add(stu);
                            stu = null;
                        }
                        break;
                }
                //一轮结束后要将解析器推进
                eventType = parser.next();
            }
            System.out.println(list);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

主要用到XmlPullParser 的如下几个方法:

  • getEventType 获取当前标签类型,一般有START_TAG, END_TAG, TEXT、START_DOCUMENT、END_DOCUMENT几种类型;
  • next 推至下个标签
  • getName 获取当前标签名字
  • getAttributeValue 获取当前标签内的属性值
  • getText 获取当前标签的text
  • nextText 获取当前标签的text,并推至EndTag标签。



版权声明:本文为SHENCHEN1987原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。