前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android基础总结(12)——XML和JSON解析

Android基础总结(12)——XML和JSON解析

作者头像
mukekeheart
发布2018-02-27 11:53:50
2.1K0
发布2018-02-27 11:53:50
举报

XML和JSON解析

   在网络上传输数据时最常用的格式有两种:XML和JSON。本文主要就是学习如何对这两种常用的数据格式进行解析。

1、XML和JSON的定义

  • XML扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML使用DTD(document type definition)文档类型定义来组织数据;格式统一,跨平台和语言,早已成为业界公认的标准。XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。
 1 <apps>
 2     <app>
 3         <id>1</id>
 4         <name>matlab</name>
 5         <version>12.5</version>
 6     </app>
 7     <app>
 8         <id>2</id>
 9         <name>chorme</name>
10         <version>9.986</version>
11     </app>
12     <app>
13         <id>3</id>
14         <name>Google Maps</name>
15         <version>10.4</version>
16     </app>
17 </apps>
  • JSONJavaScript Object Notation,一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换。JSON采用兼容性很高的、完全独立于语言文本格式,同时也具备类似于C语言的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)体系的行为。这些特性使JSON成为理想的数据交换语言。JSON基于JavaScript Programming Language , Standard ECMA-262 3rd Edition - December 1999 的一个子集。 JSON就是一串字符串,只不过元素会使用特定的符号标注。   {} 双括号表示对象   [] 中括号表示数组   "" 双引号内是属性或值   : 冒号表示后者是前者的值(这个值可以是字符串、数字、也可以是另一个数组或对象)
1 [{"id":"1","name":"matlab","version","12.5"}
2 {"id":"2","name":"chorme","version","9.986"}
3 {"id":"3","name":"Google Maps","version","10.4"}]  

2、XML和JSON的优缺点

  • XML的优缺点
    • XML的优点
      1. 格式统一,符合标准;
      2. 容易与其他系统进行远程交互,数据共享比较方便。
    • XML的缺点
      1. XML文件庞大,文件格式复杂,传输占带宽;
      2. 服务器端和客户端解析XML花费较多的资源和时间。
      3. 服务器端和客户端都需要花费大量代码来解析XML,导致服务器端和客户端代码变得异常复杂且不易维护;
      4. 客户端不同浏览器之间解析XML的方式不一致,需要重复编写很多代码;
  • 两者对比:
    • 相同点
      1. 两者的数据可读性基本相同
      2. 两者拥有同样丰富的解析手段
    • 异同点
      1. json的数据体积更小
      2. json与JS的交互更加方便
      3. json的解析速度更快
      4. xml对数据的描述性更好

3、XML和JSON的解析

  我们先整体上列一个思路,对于这两种数据格式的解析,每一种数据都有多种解析方法,本文对每一种数据都提供两种经常用到的两种方式:

  • XML格式解析Pull解析方式、SAX解析方式、DOM解析方式
    1. Pull解析方式:Pull解析器的运行方式与 SAX 解析器相似。它提供了类似的事件,如:开始元素和结束元素事件,使用parser.next()可以进入下一个元素并触发相应事件。事件将作为数值代码被发送,因此可以使用一个switch对感兴趣的事件进行处理。当元素开始解析时,调用parser.nextText()方法可以获取下一个Text类型元素的值。
 1 private void parseXMLWithPull(String xmlData){
 2     try {
 3         //创建一个xml解析的工厂
 4         XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
 5         //获得xml解析类的引用
 6         XmlPullParser xmlPullParser = factory.newPullParser();
 7         //以流的方式传入需要解析的xml数据
 8         xmlPullParser.setInput(new StringReader(xmlData));
 9         //获得事件的类型
10         int eventType = xmlPullParser.getEventType();
11         String id = "" ;
12         String name = "" ;
13         String version = "" ;
14         //判断是否到了文档结束位置
15         while(eventType != XmlPullParser.END_DOCUMENT){
16             String nodeName = xmlPullParser.getName() ;
17            switch(eventType){
18              
19               //遇到标签元素
20               case XmlPullParser.START_TAG:
21                  if("id".equals(nodeName)){
22                     //取出属性值,0是代表第0个属性
23                     id = xmlPullParser.nextText();
24                  } else if("name".equals(nodeName)){
25                     //获取该节点的内容 
26                     name = xmlPullParser.nextText();
27                  }else if("version".equals(nodeName)){
28                     //获取该节点的内容 
29                     version = xmlPullParser.nextText();
30                  }
31                  break; 
32               //标签结束
33               case XmlPullParser.END_TAG:
34                   if("app".equals(xmlPullParser.getName())){
35                      //这里可以做一些初始化,或者log记录
36                       Log.d("MainAvtivity", "id is" + id) ;
37                       Log.d("MainAvtivity", "name is" + name) ;
38                       Log.d("MainAvtivity", "version is" + version) ;
39                   }
40                  break;
41               default:
42                   break ;
43            }
44             //循环
45             eventType = xmlPullParser.next();
46         } 
47     } catch (Exception e) {
48         // TODO Auto-generated catch block
49         e.printStackTrace();
50     }
51 }
 
 1 private void parseXMLWithSAX(String xmlData){
 2     try {
 3         //第一步:新建一个工厂类SAXParserFactory,并获取其实例
 4         SAXParserFactory factory = SAXParserFactory.newInstance();
 5         //第二步:让工厂类产生一个SAX的解析类SAXParser的对象
 6         SAXParser parser = factory.newSAXParser();
 7         //第三步:从SAXPsrser中得到一个XMLReader实例
 8         XMLReader xmlReader = parser.getXMLReader();
 9         //第四步:把自己写的handler注册到XMLReader中,一般最重要的就是ContentHandler
10         MySaxHandler handler = new MySaxHandler() ;
11         xmlReader.setContentHandler(handler);
12         //第五步:将一个xml文档或者资源变成一个java可以处理的InputStream流后,解析正式开始
13         xmlReader.parse(new InputSource(new StringReader(xmlData)));
14     } catch (Exception e) {
15         // TODO Auto-generated catch block
16         e.printStackTrace();
17     }
18 }

 最重要、最关键的就是第四步,handler的实现。下面是其实现的代码:

1 /*
 2  * 实现一个ContentHandler一般要一下几个步骤:
 3  * 
 4  * 1、声明一个类,继承DefaultHandler。DefaultHandler是一个基类,这个类里面简单实现了
 5  *    一个ContentHandler。我们只需要重写里面的方法即可。
 6  * 2、重写 startDocument() 和 endDocument(),一般解析将正式解析之前的一些初始化工资放
 7  *    到startDocument()里面,收尾的工作放到endDocument()里面。
 8  * 3、重写startElement(),XML解析器遇到XML里面的tag时就会调用这个函数。经常在这个函数内是
 9  *    通过localName俩进行判断而操作一些数据。
10  * 4、重写characters()方法,这是一个回调方法。解析器执行完startElement()后,解析完节点的内
11  *    容后就会执行这个方法,并且参数ch[]就是节点的内容。这个例子里我们根据currentstate的不同,来
12  *    判断当前那个tag的内容,并放到合适的实体类中。
13  * 5、重写endElement()方法,这个方法与startElement()相对应,解析完一个tag节点后,执行这个方法。
14  *    再找个例子中,如果解析一个item结束,就将RSSIiem添加到RSSFeed中。
15  *    
16  */
17 class MySaxHandler extends DefaultHandler{
18     
19     private String nodeName ;
20     private StringBuilder id ;
21     private StringBuilder name ;
22     private StringBuilder version ;
23     
24     /**
25      * 当SAX解析器解析到XML文档开始时,会调用的方法
26      */
27     @Override
28     public void startDocument() throws SAXException {
29         id = new StringBuilder() ;
30         name = new StringBuilder() ;
31         version = new StringBuilder() ;
32     }
33     
34     /**
35      * 当SAX解析器解析到XML文档结束时,会调用的方法
36      */
37     @Override
38     public void endDocument() throws SAXException {
39         super.endDocument();
40     }
41     
42     /**
43      * 当SAX解析器解析到某个属性值时,会调用的方法
44      * 其中参数ch记录了这个属性值的内容
45      */
46     @Override
47     public void characters(char[] ch, int start, int length)throws SAXException {
48         //根据当前的节点名判断将内容添加到哪一个StringBuilder上
49         if("id".equals(nodeName)){
50             id.append(ch, start, length) ;
51         }else if("name".equals(nodeName)){
52             name.append(ch, start, length) ;
53         }else if("version".equals(nodeName)){
54             version.append(ch, start, length) ;
55         }
56     }
57     
58     /**
59      * 当SAX解析器解析到某个元素开始时,会调用的方法
60      * 其中localName记录的是元素属性名
61      */
62     @Override
63     public void startElement(String uri, String localName, String qName,
64             Attributes attributes) throws SAXException {
65         nodeName = localName ;
66     }
67     
68     /**
69      * 当SAX解析器解析到某个元素结束时,会调用的方法
70      * 其中localName记录的是元素属性名
71      */
72     @Override
73     public void endElement(String uri, String localName, String qName)
74             throws SAXException {
75         if("app".equals(localName)){
76             //这里可以做一些初始化,或者log记录
77              Log.d("MainAvtivity", "id is" + id) ;
78              Log.d("MainAvtivity", "name is" + name) ;
79              Log.d("MainAvtivity", "version is" + version) ;
80          }
81     }
82 }
  • JSON格式解析:使用JsonObject解析和使用GSON解析。可以参考:Android学习笔记45:JSON数据解析(GSON方式)
    1. 使用JsonObject解析:可以看作是一个json对象,这是系统中有关JSON定义的基本单元,其包含一对(Key/Value)数值。它对外部(External:应用toString()方法输出的数值)调用的响应体现为一个标准的字符串(例如:{"JSON": "Hello, World"},最外被大括号包裹,其中的Key和Value被冒号":"分隔)。其对于内部(Internal)行为的操作格式略微,例如:初始化一个JSONObject实例,引用内部的put()方法添加数值:new JSONObject().put("JSON", "Hello, World!"),在Key和Value之间是以逗号","分隔。Value的类型包括:Boolean、JSONArray、JSONObject、Number、String或者默认值JSONObject.NULL object。
 1 private void parseJSONWithJSONObject(String jsonData){
 2     try {
 3         JSONArray jsonArray = new JSONArray(jsonData);
 4         for (int i = 0; i < jsonArray.length(); i++) {
 5             JSONObject jsonObject = jsonArray.getJSONObject(i);
 6             String id = jsonObject.getString("id");
 7             String name = jsonObject.getString("name");
 8             String version = jsonObject.getString("version");
 9 
10             // 解析完之后对这些数据进行处理,这里我们只是Log输出
11             Log.d("MainAvtivity", "id is" + id);
12             Log.d("MainAvtivity", "name is" + name);
13             Log.d("MainAvtivity", "version is" + version);
14         }
15     } catch (Exception e) {
16         e.printStackTrace();
17     }
18 }
 1 private void parseJSONWithGson(String jsonData){
 2     Gson gson= new Gson() ;
 3     //我们借助TypeTolen将期望解析成的数据类型传入到fromJson()方法中
 4     List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>(){}.getType()) ;
 5     for(App app:appList){
 6         // 解析完之后对这些数据进行处理,这里我们只是Log输出
 7         Log.d("MainAvtivity", "id is" + app.getId());
 8         Log.d("MainAvtivity", "name is" +app.getName());
 9         Log.d("MainAvtivity", "version is" + app.getVersion());
10     }
11 }
  1 /*
 2  * 我们将一个JSON对象({}之间表示一个对象)封装成App类
 3  */
 4 class App{
 5     String id ;
 6     String name ;
 7     String version ;
 8     public String getId() {
 9         return id;
10     }
11     public void setId(String id) {
12         this.id = id;
13     }
14     public String getName() {
15         return name;
16     }
17     public void setName(String name) {
18         this.name = name;
19     }
20     public String getVersion() {
21         return version;
22     }
23     public void setVersion(String version) {
24         this.version = version;
25     }    
26 }

FastJSON:不详细解释。 

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-07-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • XML和JSON解析
    • 1、XML和JSON的定义
      • 2、XML和JSON的优缺点
        • 3、XML和JSON的解析
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档