GJSON 是一个 Go 包,它提供了一种快速而简单的方法来从 json 文档获取值。它具有单行搜索、点符号路径、迭代和解析 json 行等功能。
GJSON
也可用于Python和Rust
要开始使用GJSON
请安装 Go
并运行 go get
:
$ go get -u github.com/tidwall/gjson
获取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())
}
这将打印:
Prichard
还有用于一次获取多个值的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"]}
]
}
"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"
您还可以使用查询数据库中的第一个匹配项#(...)
,或使用查找所有匹配项#(...)#
。查询支持==
、!=
、<
、<=
、>
、>=
比较仿真以及简单模式匹配%
(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"]
请注意,在 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
直接访问该值:
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.
有多种方便的函数可以处理结果:
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
该result.Value()
函数返回一个interface{}
需要类型断言的并且是以下 Go 类型之一:
boolean >> bool
number >> float64
string >> string
null >> nil
array >> []interface{}
object >> map[string]interface{}
该result.Array()
函数返回一个值数据库。如果结果表示不存在的值,则将返回一个空数据库。如果结果不是 JSON 数据库,则返回值将是支持一个结果的数据库。
和调用能够读取所有64位,从而允许使用大型JSON整数result.Int()。result.Uint()
result.Int() int64 // -9223372036854775808 to 9223372036854775807
result.Uint() uint64 // 0 to 18446744073709551615
有一个Parse(json)函数可以执行简单的解析,然后result.Get(path)结果搜索。
例如,所有这些都会返回相同的结果:
gjson.Parse(json).Get("name").Get("last")
gjson.Get(json, "name").Get("last")
gjson.Get(json, "name.last")
有时您只是想知道某个值是否存在。
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")
}
并且Get函数Parse期望 json 格式良好。错误的 json 不会恐慌,但可能会返回意外的结果。
如果您从不可预测的来源使用 JSON,那么您可能需要在使用 GJSON 之前进行验证。
if !gjson.Valid(json) {
return errors.New("invalid json")
}
value := gjson.Get(json, "name.last")
解组为map[string]interface{}
:
m, ok := gjson.Parse(json).Value().(map[string]interface{})
if !ok {
// not a map
}
如果您的 JSON 包含在[]byte切片中,则可以使用GetBytes函数。这比Get(string(data), path)。
var json []byte = ...
result := gjson.GetBytes(json, path)
如果您正在使用该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)
}
这是原始 json 的消耗而得到的无分配子切片。该方法利用了result.Index
字段,该字段是原始数据在原始 json 中的位置。的值可能result.Index
为零,在这种情况下result.Raw
会转换为[]byte
。
该GetMany
函数可用于同时获取多个值。
results := gjson.GetMany(json, "name.first", "name.last", "age")
返回值是 a []Result
,将始终包含与输入路径两个数量的项目。