• Golang-GJSON 快速而简单的方法来从 json 文档获取值


    在这里插入图片描述

    GJSON 是一个 Go 包,它提供了一种快速而简单的方法来从 json 文档获取值。它具有单行搜索、点符号路径、迭代和解析 json 行等功能。

    GJSON 也可用于PythonRust

    入门

    安装中

    要开始使用GJSON 请安装 Go 并运行 go get

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

    获取一个值

    获取json中搜索指定路径。路径采用点语法,例如“name.last”或“age”。当找到该值时,它会立即返回。

    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())
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这将打印:

    Prichard
    
    • 1

    还有用于一次获取多个值的GetMany函数,以及用于处理 JSON 字节切片的GetBytes

    路径语法

    下面是路径语法的快速概述,有关更完整的信息,请查看 GJSON 语法

    路径是一系列由点分隔的键。键可以特殊通配符“*”和“?”。要访问集群中的元素数,请使用索引作为键。要获取集群中的元素数或访问子路径,请使用“# ”字符。点和通配符可以用“\”转义。

    {
      "name": {"first": "Tom", "last": "Anderson"},
      "age":37,
      "children": ["Sara","Alex","Jack"],
      "fav.movie": "Deer Hunter",
      "friends": [
        {"first": "Dale", "last": "Murphy", "age": 44, "nets": ["ig", "fb", "tw"]},
        {"first": "Roger", "last": "Craig", "age": 68, "nets": ["fb", "tw"]},
        {"first": "Jane", "last": "Murphy", "age": 47, "nets": ["ig", "tw"]}
      ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    "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"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    您还可以使用查询数据库中的第一个匹配项#(...),或使用查找所有匹配项#(...)#。查询支持==!=<<=>>= 比较仿真以及简单模式匹配%(like)和!% (not like)。

    friends.#(last=="Murphy").first    >> "Dale"
    friends.#(last=="Murphy")#.first   >> ["Dale","Jane"]
    friends.#(age>45)#.last            >> ["Craig","Murphy"]
    friends.#(first%"D*").last         >> "Murphy"
    friends.#(first!%"D*").last        >> "Craig"
    friends.#(nets.#(=="fb"))#.first   >> ["Dale","Roger"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请注意,在 v1.3.0 之前,查询使用#[…]逗号。这在 v1.3.0 中进行了更改,小区与新的 多路径语法不一致。为了兼容, #[…]将继续工作直到下一个主要版本。

    结果类型

    GJSON 支持 json 类型string、number、bool和null。恢复和恢复对象原始 json 类型返回。

    该Result类型包含以下之一:

    bool, for JSON booleans
    float64, for JSON numbers
    string, for JSON string literals
    nil, for JSON null
    
    • 1
    • 2
    • 3
    • 4

    直接访问该值:

    result.Type           // can be String, Number, True, False, Null, or JSON
    result.Str            // holds the string
    result.Num            // holds the float64 number
    result.Raw            // holds the raw json
    result.Index          // index of raw value in original json, zero means index unknown
    result.Indexes        // indexes of all the elements that match on a path containing the '#' query character.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    有多种方便的函数可以处理结果:

    result.Exists() bool
    result.Value() interface{}
    result.Int() int64
    result.Uint() uint64
    result.Float() float64
    result.String() string
    result.Bool() bool
    result.Time() time.Time
    result.Array() []gjson.Result
    result.Map() map[string]gjson.Result
    result.Get(path string) Result
    result.ForEach(iterator func(key, value Result) bool)
    result.Less(token Result, caseSensitive bool) bool
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    result.Value()函数返回一个interface{}需要类型断言的并且是以下 Go 类型之一:

    boolean >> bool
    number  >> float64
    string  >> string
    null    >> nil
    array   >> []interface{}
    object  >> map[string]interface{}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    result.Array()函数返回一个值数据库。如果结果表示不存在的值,则将返回一个空数据库。如果结果不是 JSON 数据库,则返回值将是支持一个结果的数据库。

    64位整数

    和调用能够读取所有64位,从而允许使用大型JSON整数result.Int()。result.Uint()

    result.Int() int64    // -9223372036854775808 to 9223372036854775807
    result.Uint() uint64   // 0 to 18446744073709551615
    
    • 1
    • 2

    简单解析并获取

    有一个Parse(json)函数可以执行简单的解析,然后result.Get(path)结果搜索。

    例如,所有这些都会返回相同的结果:

    gjson.Parse(json).Get("name").Get("last")
    gjson.Get(json, "name").Get("last")
    gjson.Get(json, "name.last")
    
    • 1
    • 2
    • 3

    检查值是否存在

    有时您只是想知道某个值是否存在。

    value := gjson.Get(json, "name.last")
    if !value.Exists() {
    	println("no last name")
    } else {
    	println(value.String())
    }
    
    // Or as one step
    if gjson.Get(json, "name.last").Exists() {
    	println("has a last name")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    验证 JSON

    并且Get函数Parse期望 json 格式良好。错误的 json 不会恐慌,但可能会返回意外的结果。

    如果您从不可预测的来源使用 JSON,那么您可能需要在使用 GJSON 之前进行验证。

    if !gjson.Valid(json) {
    	return errors.New("invalid json")
    }
    value := gjson.Get(json, "name.last")
    
    • 1
    • 2
    • 3
    • 4

    解析到Map

    解组为map[string]interface{}

    m, ok := gjson.Parse(json).Value().(map[string]interface{})
    if !ok {
    	// not a map
    }
    
    • 1
    • 2
    • 3
    • 4

    解析使用[]byte

    如果您的 JSON 包含在[]byte切片中,则可以使用GetBytes函数。这比Get(string(data), path)。

    var json []byte = ...
    result := gjson.GetBytes(json, path)
    
    • 1
    • 2

    如果您正在使用该gjson.GetBytes(json, path)函数并且希望避免转换result.Raw a []byte,那么您可以使用以下模式:

    var json []byte = ...
    result := gjson.GetBytes(json, path)
    var raw []byte
    if result.Index > 0 {
        raw = json[result.Index:result.Index+len(result.Raw)]
    } else {
        raw = []byte(result.Raw)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这是原始 json 的消耗而得到的无分配子切片。该方法利用了result.Index字段,该字段是原始数据在原始 json 中的位置。的值可能result.Index为零,在这种情况下result.Raw会转换为[]byte

    一次获得多个值

    GetMany函数可用于同时获取多个值。

    results := gjson.GetMany(json, "name.first", "name.last", "age")
    
    • 1

    返回值是 a []Result,将始终包含与输入路径两个数量的项目。

  • 相关阅读:
    《数字图像处理-OpenCV/Python》连载(22)绘制直线与线段
    【注解】概述、自定义注解以及元注解
    手把手带你实现基于 Vite+Vue3 的在线Excel表格系统
    Redis(主从复制、哨兵模式、集群)概述及部署
    手游联运平台都具备哪些功能?
    数据库扩容也可以如此丝滑,MySQL千亿级数据生产环境扩容实战
    基于JAVA的电子书城系统(Web)
    路由的控制与转发原理
    Apache Seata -- 一款开源的分布式事务解决方案
    根据上下级关系统计数据
  • 原文地址:https://blog.csdn.net/weixin_43064185/article/details/132697468