五、Groovy语法(五)json、xml解析

Groovy数据解析

一、json解析

//groovy中也可导入gson、fastJson等json解析库,与java中一致

//但是groovy中提供了使用起来更加简洁的方式
class Person {
    String name
    Integer age
}


def personList = [new Person(name: 'java', age: 28), new Person(name: 'groovy', age: 6)]

//将对象解析成json字符串
def result = JsonOutput.toJson(personList)
println result //[{"age":28,"name":"java"},{"age":6,"name":"groovy"}]

println JsonOutput.prettyPrint(result) //格式化输出
/**
 [
    {
        "age": 28,
        "name": "java"
    },
    {
        "age": 6,
        "namgovy"
    }
 ]
 */
 
 
//将json字符串传化为对象
def jsonSlurper = new JsonSlurper()
def objectResult = (ArrayList<Person>) jsonSlurper.parseText(result)
Person p = objectResult[0]
println "the name is $p.name,the age is $p.age" //输出结果:the name is java,the age is 28


  • 请求网络数据并解析
def getNetWorkData(String url) {
    //发送http请求(此处用原生的,也可导入okHttp库进行网络操作)
    HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection()
    connection.setConnectTimeout(10000)
    connection.setRequestMethod('GET')
    connection.connect()
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))
    StringBuffer stringBuffer = new StringBuffer()
    String json = ""
    while ((json = bufferedReader.readLine()) != null) {
        stringBuffer.append(json)
    }
    String rsp = new String(stringBuffer.toString().getBytes(), "UTF-8")
    //解析
    def jsonSlurper = new JsonSlurper()
    return jsonSlurper.parseText(rsp)
}


/*
{"data":[{"desc":"一起来做个App吧","id":10,"imagePath":"http://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png","isVisible":1,"order":2,"title":"一起来做个App吧","type":0,"url":"http://www.wanandroid.com/blog/show/2"},{"desc":"","id":4,"imagePath":"http://www.wanandroid.com/blogimgs/ab17e8f9-6b79-450b-8079-0f2287eb6f0f.png","isVisible":1,"order":0,"title":"看看别人的面经,搞定面试~","type":1,"url":"http://www.wanandroid.com/article/list/0?cid=73"},{"desc":"","id":3,"imagePath":"http://www.wanandroid.com/blogimgs/fb0ea461-e00a-482b-814f-4faca5761427.png","isVisible":1,"order":1,"title":"兄弟,要不要挑个项目学习下?","type":1,"url":"http://www.wanandroid.com/project"},{"desc":"","id":6,"imagePath":"http://www.wanandroid.com/blogimgs/62c1bd68-b5f3-4a3c-a649-7ca8c7dfabe6.png","isVisible":1,"order":1,"title":"我们新增了一个常用导航Tab~","type":1,"url":"http://www.wanandroid.com/navi"},{"desc":"","id":2,"imagePath":"http://www.wanandroid.com/blogimgs/90cf8c40-9489-4f9d-8936-02c9ebae31f0.png","isVisible":1,"order":2,"title":"JSON工具","type":1,"url":"http://www.wanandroid.com/tools/bejson"},{"desc":"","id":5,"imagePath":"http://www.wanandroid.com/blogimgs/acc23063-1884-4925-bdf8-0b0364a7243e.png","isVisible":1,"order":3,"title":"微信文章合集","type":1,"url":"http://www.wanandroid.com/blog/show/6"}],"errorCode":0,"errorMsg":""}
*/

class Root {
    List<Data> data
    int errorCode
    String errorMsg

    class Data {
        String desc
        int id
        String imagePath
        int isVisible
        int order
        String title
        int type
        String url
    }
}

Root root = getNetWorkData("http://www.wanandroid.com/banner/json")
println root.data[0].imagePath //输出结果:http://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png

//以上是类似java的做法,而在Groovy中,不需要写实体类,可直接使用里面的字段
def response = getNetWorkData("http://www.wanandroid.com/banner/json")
println response.data[0].imagePath //输出结果:http://www.wanandroid.com/blogimgs/50c115c2-cf6c-4802-aa7b-a4334de444cd.png

二、xml解析

  1. groovy解析xml数据
def xmlStr = '''
<response version-api="2.0">
        <value>
            <books id="1" classification="android">
                <book available="20" id="1">
                    <title>Android组件化架构</title>
                    <author id="1">苍王</author>
                </book>
                <book available="14" id="2">
                   <title>Android 插件化开发指南</title>
                   <author id="2">包建强</author>
               </book>
               <book available="13" id="3">
                   <title>Android开发艺术探索</title>
                   <author id="3">任玉刚</author>
               </book>
               <book available="5" id="4">
                   <title>Android源码设计模式2</title>
                   <author id="4">何红辉</author>
               </book>
           </books>
           <books id="2" classification="web">
               <book available="10" id="1">
                   <title>Vue从入门到精通</title>
                   <author id="4">李刚</author>
               </book>
           </books>
       </value>
    </response>
'''

//开始解析
def xmlSlurper = new XmlSlurper()
def response = xmlSlurper.parseText(xmlStr) //解析出来的即为根节点

//输出节点中对应节点的值
println response.value.books[0].book[1].title.text() //Android 插件化开发指南
//输出节点中属性的值,直接使用@
println response.value.books[0].book[1].@id //2

//遍历
def list = []
response.value.books.each { books ->
    //再对books中的book节点遍历
    books.book.each { book ->
        def author = book.author.text()
        if ('任玉刚' == author) {
            list.add(book.title.text())
        }
    }
}

println list.toListString()  // [Android开发艺术探索]

//groovy提供了另外的遍历xml方法
//深度遍历
def list2 = []
response.depthFirst().findAll { book ->
    if ('任玉刚' == book.author.text()){
        list2.add(book.title.text())
        return true
    }
}

println list2.toListString()  //[Android开发艺术探索]


def titles = response.depthFirst().findAll { book ->
    '任玉刚' == book.author.text()
}.collect { book->
    book.title.text()
}
println titles.toListString()  //[Android开发艺术探索]


//广度遍历
def titles2 = response.value.books.children().findAll { node ->
    ('2'.compareTo((node.@id).toString())) < 0
}.collect { book ->
    book.title.text()
}
println titles2 //[Android开发艺术探索, Android源码设计模式2]
  1. groovy创建xml数据
  • 手写创建
def sw = new StringWriter()
//用来生成xml
def xmlBuilder = new MarkupBuilder(sw)

//创建根节点response并且添加属性version_api
xmlBuilder.response(version_api: '2.0') {
    //在response中创建value节点
    value() {
        //在value中创建books节点
        books(id: '1', classification: 'android') {
            //在books节点中创建book节点
            book(available: '20', id: '1') {
                //创建title节点,(value为Android组件化架构,即title.text()的值)
                title('Android组件化架构') {}
                //创建author节点
                author(id: '1', '苍王') {}
            }
            //第二个book节点
            book(available: '14', id: '2') {
                title('Android插件化开发指南') {}
                author(id: '2', '包建强') {}
            }

            //第三个book节点
            book(available: '13', id: '3') {
                title('Android开发艺术探索') {}
                author(id: '3', '任玉刚') {}
            }

            //第四个book节点
            book(available: '5', id: '4') {
                title('Android源码设计模式2') {}
                author(id: '4', '何红辉') {}
            }
        }

        //创建第二个books节点
        books(id: '2', classification: 'web') {
            //在books节点中创建book节点
            book(available: '10', id: '1') {
                //创建title节点,(value为Android组件化架构,即title.text()的值)
                title('Vue从入门到精通') {}
                //创建author节点
                author(id: '4', '李刚') {}
            }
        }
    }
}

println sw //输出结果
 '''
 <response version_api="2.0">
        <value>
            <books id="1" classification="android">
                <book available="20" id="1">
                    <title>Android组件化架构</title>
                    <author id="1">苍王</author>
                </book>
                <book available="14" id="2">
                   <title>Android 插件化开发指南</title>
                   <author id="2">包建强</author>
               </book>
               <book available="13" id="3">
                   <title>Android开发艺术探索</title>
                   <author id="3">任玉刚</author>
               </book>
               <book available="5" id="4">
                   <title>Android源码设计模式2</title>
                   <author id="4">何红辉</author>
               </book>
           </books>
           <books id="2" classification="web">
               <book available="10" id="1">
                   <title>Vue从入门到精通</title>
                   <author id="4">李刚</author>
               </book>
           </books>
       </value>
    </response>
'''
  • 根据服务器获取对象数据创建

//模仿服务器中已有的数据
class Response {
    String version_api
    Value value
}

class Value {
    def books = [new Books(id: '1', classification: 'android', book: [new Book(available: '20', id: '1', title: new Title(value: 'Android组件化架构'), author: new Author(id: '1', value: '苍王'))
                                                                      , new Book(available: '14', id: '2', title: new Title(value: 'Android插件化开发指南'), author: new Author(id: '2', value: '包建强'))
                                                                      , new Book(available: '13', id: '3', title: new Title(value: 'Android开发艺术探索'), author: new Author(id: '3', value: '任玉刚'))
                                                                      , new Book(available: '5', id: '4', title: new Title(value: 'Android源码设计模式2'), author: new Author(id: '4', value: '何红辉'))]),
                 new Books(id: '2', classification: 'web', book: [new Book(available: '10', id: '1', title: new Title(value: 'Vue从入门到精通'), author: new Author(id: '4', value: '李刚'))])]
}

class Books {
    String id
    String classification
    ArrayList<Book> book
}

class Book {
    String available
    String id
    Title title
    Author author
}

class Title {
    def value
}

class Author {
    def id
    def value
}


def sw2 = new StringWriter()
//用来生成xml
def xmlBuilder2 = new MarkupBuilder(sw2)
//初始化数据,假设是从服务器中获取的数据
def response2 = new Response(version_api: '2.0', value: new Value())

xmlBuilder2.response(version_api: "$response2.version_api") {
    value() {
        response2.value.books.each { booksNode ->
            //循环创建books节点
            books(id: booksNode.id, classification: booksNode.classification) {
                booksNode.book.each { bookNode ->
                    //循环创建book节点
                    book(available: bookNode.available, id: bookNode.id) {
                        title("$bookNode.title.value")
                        author(id: "$bookNode.author.id", "$bookNode.title.value")
                    }
                }
            }
        }
    }
}

println sw2 //输出结果

 '''
<response version_api='2.0'>
  <value>
    <books id='1' classification='android'>
      <book available='20' id='1'>
        <title>Android组件化架构</title>
        <author id='1'>Android组件化架构</author>
      </book>
      <book available='14' id='2'>
        <title>Android插件化开发指南</title>
        <author id='2'>Android插件化开发指南</author>
      </book>
      <book available='13' id='3'>
        <title>Android开发艺术探索</title>
        <author id='3'>Android开发艺术探索</author>
      </book>
      <book available='5' id='4'>
        <title>Android源码设计模式2</title>
        <author id='4'>Android源码设计模式2</author>
      </book>
    </books>
    <books id='2' classification='web'>
      <book available='10' id='1'>
        <title>Vue从入门到精通</title>
        <author id='4'>Vue从入门到精通</author>
      </book>
    </books>
  </value>
</response>
'''

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

推荐阅读更多精彩内容

  • JSON JSON和XML都是需要解析的 JSON是一种轻量级的数据格式,一般用于数据交互服务器返回给客户端的数据...
    JonesCxy阅读 1,849评论 2 10
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,093评论 1 32
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,450评论 1 45
  • 一. XML数据交换格式 XML数据交换格式是一种自描述的数据交互格式,虽然XML数据格式不如JSON "轻便",...
    __season____阅读 2,495评论 0 7
  • 考拉海购在过去一年中的版本更新记录大致分为: 在最初的阶段,满足能买商品的情况下,优先做了优惠券,秒杀和把用户...
    白熊S阅读 1,628评论 0 14