要使用gjson,先要安装go环境并执行go get:
$ go get -u github.com/tidwall/gjson
以上命令会检索并下载该库到Go环境中。
Get在json中搜索指定的路径。路径用点语法表示,比如“name.last"或“age"。这个函数需要提供格式正规和有效的json值。无效的json不会引起panic,但它可能返回意外的结果。当找到值后立即返回。
package main
import "github.com/tidwall/gjson"
const json = `{"name":{"first":"Janet","last":"Prichard"},"age":47}`
func main() {
result := gjson.Get(json, "name.last")
println(result.String())
}
output
Prichard
还有用于处理JSON字节切片的GetBytes(https://links.jianshu.com/go?to=https%3A%2F%2Fwww.ctolib.com%2Fgjson.html%23working-
with-bytes) 函数。
path是由点分隔的一系列键。key可以包含特殊的通配符'*'和'?'。要访问数组值,请使用索引作为键。要获取数组中的元素数量或访问子路径,请使用'#'字符。点和通配符可以用'\'转义。
{
"name": {"first": "Tom", "last": "Anderson"},
"age":37,
"children": ["Sara","Alex","Jack"],
"fav.movie": "Deer Hunter",
"friends": [
{"first": "James", "last": "Murphy"},
{"first": "Roger", "last": "Craig"}
]
}
"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" >> ["James","Roger"]
"friends.1.last" >> "Craig"
查询一个数组:
`friends.#[last="Murphy"].first` >> "James"
GJSON支持json类型字符串,数字,bool和null。数组和对象作为原始json类型返回。
Result类型包含以下类型之一:
bool, for JSON booleans
float64, for JSON numbers
string, for JSON string literals
nil, for JSON null
要直接访问该值:
result.Type // 可能是String, Number, True, False, Null, or JSON
result.Str // 保存string
result.Num // 保存float64
result.Raw // 保存 raw json
result.Index // json中原始值的索引,0表示索引未知
result有很多函数:
result.Value() interface{}
result.Int() int64
result.Uint() uint64
result.Float() float64
result.String() string
result.Bool() bool
result.Array() []gjson.Result
result.Map() map[string]gjson.Result
result.Get(path string) Result
result.Value返回一个interface{},需要断言,是以下类型之一:
boolean >> bool
number >> float64
string >> string
null >> nil
array >> []interface{}
object >> map[string]interface{}
result.Array()返回一个数组。如果result代表一个不存在的值,那么将返回一个空数组。如果result不是一个JSON数组,返回值将是一个包含一个结果的数组。
假设你想要以下json中的所有lastName对应值:
{
"programmers": [
{
"firstName": "Janet",
"lastName": "McLaughlin",
}, {
"firstName": "Elliotte",
"lastName": "Hunter",
}, {
"firstName": "Jason",
"lastName": "Harold",
}
]
}
您将使用路径“programmers.#.lastName“像这样:
result := gjson.Get(json, "programmers.#.lastName")
for _,name := range result.Array() {
println(name.String())
}
你也可以查询数组中的对象:
name := gjson.Get(json, `programmers.#[lastName="Hunter"].firstName`)
println(name.String()) // 输出 "Elliotte"
有一个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())
}
// 或一步到位
if gjson.Get(json, "name.last").Exists(){
println("has a last name")
}
m, ok := gjson.Parse(json).Value().(map[string]interface{})
if !ok{
// 不是map
}
如果json存在[]byte切片中,有一个
函数。首选使用:Get(string(data), path)
var json []byte = ...
result := gjson.GetBytes(json, path)
如果你使用gjson.GetBytes(json, path)函数,想避免将result.raw转换到[]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的值可能等于0,这种情况下result.Raw被转成[]byte。
与encoding/json, ffjson, EasyJSON和jsonparser,对比 GJSON的基准测试:
BenchmarkGJSONGet-8 15000000 333 ns/op 0 B/op 0 allocs/op
BenchmarkGJSONUnmarshalMap-8 900000 4188 ns/op 1920 B/op 26 allocs/op
BenchmarkJSONUnmarshalMap-8 600000 8908 ns/op 3048 B/op 69 allocs/op
BenchmarkJSONUnmarshalStruct-8 600000 9026 ns/op 1832 B/op 69 allocs/op
BenchmarkJSONDecoder-8 300000 14339 ns/op 4224 B/op 184 allocs/op
BenchmarkFFJSONLexer-8 1500000 3156 ns/op 896 B/op 8 allocs/op
BenchmarkEasyJSONLexer-8 3000000 938 ns/op 613 B/op 6 allocs/op
BenchmarkJSONParserGet-8 3000000 442 ns/op 21 B/op 0 allocs/op
使用的json文档:
{
"widget": {
"debug": "on",
"window": {
"title": "Sample Konfabulator Widget",
"name": "main_window",
"width": 500,
"height": 500
},
"image": {
"src": "Images/Sun.png",
"hOffset": 250,
"vOffset": 250,
"alignment": "center"
},
"text": {
"data": "Click Here",
"size": 36,
"style": "bold",
"vOffset": 100,
"alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
}
}
}
执行的搜索操作:
widget.window.name
widget.image.hOffset
widget.text.onMouseUp
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有