gjson

aside section ._1OhGeD · · 4019 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang中gjson

开始

$ go get -u github.com/tidwall/gjson

JSON串

获取值

Get查询指定路径, 通过.来区分. 比如"name.last"或者"age". 如果找到了匹配路径, 将返回结果.

同时有 GetMany 方法批量获取值, 也有 GetBytes 方法获取字节切片.

package main

import "github.com/tidwall/gjson"

const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`

func main() {
    value := gjson.Get(json, "name.last")
    println(value.String())
    results := gjson.GetMany(json, "name.last", "age")
    for _, result := range results {
        println(result.String())
    }
    value = gjson.GetBytes([]byte(json), "name.last")
    println(value.String())
}

遍历

例1.

package main

import "github.com/tidwall/gjson"

const json1 = `{"name":{"name":"zhangsan","age":47},"name1":{"name":"lisi","age":42}}`

func main() {
    gjson.Get(json1, "name1").ForEach(printKeyValue())
}

func printKeyValue() func(key gjson.Result, value gjson.Result) bool {
    return func(key, value gjson.Result) bool {
        println(key.String(), ":", value.String())
        return true
    }
}

例2.

package main

import "github.com/tidwall/gjson"

const json = `{"name":"zhangsan","age":47}`

func main() {
    gjson.Parse(json).ForEach(printKeyValue())

}

func printKeyValue() func(key gjson.Result, value gjson.Result) bool {
    return func(key, value gjson.Result) bool {
        println(key.String(), ":", value.String())
        return true
    }
}

JSON数组

获取值

例1.

package main

import "github.com/tidwall/gjson"

const jsonArray = `{
  "names": [
    {
      "name": "zhangsan"
    },
    {
      "name": "lisi"
    }
  ]
}`

func main() {
    value := gjson.Get(jsonArray, "names.0.name")
    println(value.String())
    value = gjson.Get(jsonArray, "names.1.name")
    println(value.String())
}

例2.

package main

import (
    "fmt"
    "github.com/tidwall/gjson"
)

const jsonArray = `[
    {
      "name": "zhangsan",
      "address": "beijing"
    },
    {
      "name": "lisi",
      "address": "tianjin"
    }
  ]
`

func main() {
    valur := gjson.Get(jsonArray, "0.name")
    fmt.Println(valur.String())
}

遍历

例1.

package main

import (
    "fmt"
    "github.com/tidwall/gjson"
)

const jsonArray = `{
  "names": [
    {
      "name": "zhangsan",
      "address": "beijing"
    },
    {
      "name": "lisi",
      "address": "tianjin"
    }
  ]
}`

func main() {
    for _, res := range gjson.Get(jsonArray, "names").Array() {
        res.ForEach(func(key, value gjson.Result) bool {
            fmt.Println(key.String(), ":", value.String())
            return true
        })
    }
}

例2.

package main

import (
    "fmt"
    "github.com/tidwall/gjson"
)

const jsonArray = `[
    {
      "name": "zhangsan",
      "address": "beijing"
    },
    {
      "name": "lisi",
      "address": "tianjin"
    }
  ]
`

func main() {
    for _, res := range gjson.Parse(jsonArray).Array() {
        res.ForEach(func(key, value gjson.Result) bool {
            fmt.Println(key.String(), ":", value.String())
            return true
        })
    }
}

路径解析

  • 路径是一系列被.分隔的key拼接而成.
  • 路径可能包含通配符'*'和'?'.
  • 通过下标访问数组值.
  • 通过'#'来获取值在元素中的排位或访问子路径.
  • .和通配符可以通过''来转义.
{
  "name": {"first": "Tom", "last": "Anderson"},
  "age":37,
  "children": ["Sara","Alex","Jack"],
  "fav.movie": "Deer Hunter",
  "friends": [
    {"first": "Dale", "last": "Murphy", "age": 44},
    {"first": "Roger", "last": "Craig", "age": 68},
    {"first": "Jane", "last": "Murphy", "age": 47}
  ]
}

"name.last"          >> "Anderson"
"age"                >> 37
"children"           >> ["Sara","Alex","Jack"]
"children.#"         >> 3
"children.1"         >> "Alex"
"child*.2"           >> "Jack"
"c?ildren.0"         >> "Sara"
"fav\.movie"         >> "Deer Hunter"
"friends.#.first"    >> ["Dale","Roger","Jane"]
"friends.1.last"     >> "Craig"

同样能通过#[...]来查询数组中的第一个匹配的项, 或通过'#[...]#'查询所有匹配的项.
查询支持==, !=, <, <=, >, >=比较运算符和'%'模糊匹配.

friends.#[last=="Murphy"].first    >> "Dale"
friends.#[last=="Murphy"]#.first   >> ["Dale","Jane"]
friends.#[age>45]#.last            >> ["Craig","Murphy"]
friends.#[first%"D*"].last         >> "Murphy"

JSON行

同样支持JSON Lines, 使用 .. 前缀, 把多行文档视作数组.

比如:

{"name": "Gilbert", "age": 61}
{"name": "Alexa", "age": 34}
{"name": "May", "age": 57}
{"name": "Deloise", "age": 44}

..#                   >> 4
..1                   >> {"name": "Alexa", "age": 34}
..3                   >> {"name": "Deloise", "age": 44}
..#.name              >> ["Gilbert","Alexa","May","Deloise"]
..#[name="May"].age   >> 57
ForEachLines 方法可以迭代json.

例1.

package main

import "github.com/tidwall/gjson"

const jsonRow = `{"name": "Gilbert", "age": 61}
{"name": "Alexa", "age": 34}
{"name": "May", "age": 57}
{"name": "Deloise", "age": 44}`

func main() {
    println(gjson.Get(jsonRow, "..1").String())
}

例2.


package main

import "github.com/tidwall/gjson"

const jsonRow = `{"name": "Gilbert", "age": 61}
{"name": "Alexa", "age": 34}
{"name": "May", "age": 57}
{"name": "Deloise", "age": 44}`

func main() {
    gjson.ForEachLine(jsonRow, func(line gjson.Result) bool {
        println(line.Get("name").String())
        return true
    })
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:aside section ._1OhGeD

查看原文:gjson

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

4019 次点击  ∙  1 赞  
加入收藏 微博
下一篇:Day 1
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传