解析数据

1.XML格式数据解析

XML格式数据:
<apps>
  <app>
    <id>1</id>
    <name>Google Maps</name>
    <version>1.0</version>
  </app>
  <app>...</app>
</apps>

  • Pull解析:

 首先,利用工厂方法获得XmlPullParser实例对象。

XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xmlPullParser = factory.newPullParser();

 接下来,将服务器返回的数据传入获得XML数据的相关信息(eventType)。

//设置输入流
xmlPullParser.setInput(new StringReader(xmlData));
//获得当前的解析事件
int eventType = xmlPullParser.getEventType();

 根据当前解析事件的类型进行循环读取、解析

while(eventType != XmlPullParser.END_DOCUMENT) {
     String nodeName = xmlPullParser.getName();
     switch(eventType) {
      //开始解析节点
      case XmlPullParser.START_TAG: {
         if("id".equals(nodeName)) {
            id = xmlPullParser.nextText();
            } else if ("name".equals(nodeName)) {
            name = xmlPullParser.nextText();
            } else if ("version".equals(nodeName)) {
            version = xmlPullParser.nextText();
            }
            break;
       }
       //完成解析某个节点
       case XmlPullParser.END_TAG:{
         if ("app".equals(nodeName)) {
         //输出信息
              Log.d("MainActivity","id is " + id);
              Log.d("MainActivity","name is " + name);
              Log.d("MainActivity","version is " + version);
          }
          break;
        }
        default :
              break;
      }
      //获取下一个解析事件 
      eventType = xmlPullParser.next();
}
  • SAX解析
     首先,新建一个类继承DefaulfHandler,并重写父类的5个方法
     每当开始解析某个节点的时候,startElement()方法就会得到调用,其中localName参数记录着当前节点的名字
     接着在解析节点中具体内容的时候就会调用characters()方法,根据当前节点名(在startElement()方法中获得)进行判断,将解析出的内容添加到对应的StringBuilder对象中。
    最后endElement()方法中进行判断,如果app节点已经解析完成,就打印出id、name和version的内容,并清空StringBuilder
public class MyHandler extends DefaultHandler {
    private String nodeName;
    private StringBuilder id;
    private StringBuilder name;
    private StringBuilder version;


    /**
     * 在开始XML解析时调用
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
       id = new StringBuilder();
       name = new StringBuilder();
       version = new StringBuilder();
    }

    /**
     * 在完成整个XML解析时调用
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    /**
     * 在开始解析某个节点时调用
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //记录当前节点名
        nodeName = localName;
    }

    /**
     * 在完成解析某个节点时调用
     * @param uri
     * @param localName
     * @param qName
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
       if ("app".equals(localName)) {
           Log.d("MyHandler", "id is " + id.toString().trim());
           Log.d("MyHandler", "name is " + name.toString().trim());
           Log.d("MyHandler", "version is " + version.toString().trim());
           //将StringBuilder清空
           id.setLength(0);
           name.setLength(0);
           version.setLength(0);
       }
    }

    /**
     * 获取节点中间内容的时候调用
     * @param ch
     * @param start
     * @param length
     * @throws SAXException
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        //根据当前的节点名判断将内容添加到哪一个StringBuilder对象中
        if ("id".equals(nodeName)) {
            id.append(ch, start, length);
        } else if ("name".equals(nodeName)) {
            name.append(ch, start, length);
        } else if ("version".equals(nodeName)) {
            version.append(ch, start, length);
        }
    }
}

 父类的方法重写完毕后调用工厂方法构建XMLReader的实例对象,将MyHandler的实例设置到XMLReader中。

        SAXParserFactory factory = SAXParserFactory.newInstance();
        XMLReader xmlReader = factory.newSAXParser().getXMLReader();
        MyHandler myHandler = new MyHandler();
        //将MyHandler的实例设置到XMLReader中
        xmlReader.setContentHandler(myHandler);
        //构建输入流,开始解析,数据在MyHandler中进行处理
        xmlReader.parse(new InputSource(new StringReader(xmlData)));

2.JSON格式数据解析

JSON具有体积小的优势,在数据传输中会经常被使用。

JSON格式:
 [{"id":"5","version":"5.5","name":"Clash of Clans"},
 {"id":"6","version":"7.0","name":"Boom Beach"},
 {"id":"7","version":"3.5","name":"Clash Royale"}]

解析JSON数据的方法有很多种,这里主要介绍JSONObjectGSON

  • JSONObject

 在介绍JSONObject之前,需要介绍一个JSONArray的概念。以上面的JSON格式的数据为例,"{ }"内的信息为一个JSONObject"[ ]"内的信息是由3个JSONObject组成的一个JSONArray
 当返回的数据格式是JSONArray时,循环遍历这个JSONArray从中取出每一个元素都是一个JSONObject对象每个JSONObject对象包含所需要的信息

//当返回信息的格式为JSONArray
  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");
        }
//当返回信息格式为JSONObject
 JSONObject jsonObject = new JSONObject(jsonData);
            String id = jsonObject.getString("id");
            String name = jsonObject.getString("name");
            String version = jsonObject.getString("version");
  • GSON
     使用GSON从服务器获取数据,需要建立相应的JavaBean形成相应的映射
public class App {
    //JavaBean的属性名称需要与想要获取的JSON格式中的数据名称保持一致
    private String id;//"id"
    private String name;
    private String version;

    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 getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }
}

 当返回的数据是JSONObject时:

    Gson gson = new Gson();
    App app = gson.fromJson(jsonData, App.class);

 当返回的数据是JSONArray时,需要借助TypeToken类(需要匿名类来调构造函数)期望解析成的数据类型传入fromJson()方法中:

    Gson gson = new Gson();
    List<App> appList = gson.fromJson(jsonData,
                              //利用TypeToken的匿名类来构建实例
                              new TypeToken<List<App>>(){ }.getType());
    for(App app : appList) {
          Log.d("TAG", "id is " + app.getId());
          Log.d("TAG", "name is " + app.getName());
          Log.d("TAG", "version is " + app.getVersion());

    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,110评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,443评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,474评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,881评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,902评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,698评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,418评论 3 419
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,332评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,796评论 1 316
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,968评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,110评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,792评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,455评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,003评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,130评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,348评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,047评论 2 355

推荐阅读更多精彩内容

  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,393评论 8 265
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,662评论 18 139
  • 九小姐传出来了,百姓津津乐道的却另有其人。 九小姐既是老爷子承认的嫡出小姐,那自然是当...
    惜之退之阅读 170评论 0 0
  • 大家现在好,今天做了转正述职汇报,我爱我自己,今天拔河比赛冠军,我爱我自己,今天翻看以前艺术照,我要健康的瘦下...
    心羽暖姐姐阅读 163评论 0 0
  • 因为出生的时间段,我错过了83年最火的射雕英雄传,现在看郭靖宇导演的新射雕,真是秒杀之前所有版本,超级好看,黄蓉,...
    云牵阅读 137评论 0 0