GJSON 是一个用于处理 JSON 数据的 Go 语言库。它提供了一些方便的功能,例如解析 JSON 字符串、查询 JSON 对象、生成 JSON 对象等
下载gjson: go get -u github.com/tidwall/gjson
1、使用
传入 JSON 串和要读取的键路径,路径使用点号语法,如 "name.last "或 "age"。一旦找到值,就会立即返回。
路径是一系列用点分隔的键。键可以包含特殊的通配符 "*"和"? 要访问数组值,使用索引作为键。要获取数组中的元素个数或访问子路径,请使用 "#"字符。点和通配符可以用'\'转义。
例:
package main import ( "fmt" "github.com/tidwall/gjson" ) func main() { //{ // "name": {"first": "Tom", "last": "Anderson"}, // "age":37, // "children": ["Sara","Alex","Jack"], // "friends": [ // {"first": "James", "last": "Murphy"}, // {"first": "Roger", "last": "Craig"} // ] // } //设置json字符串 jsonStr := `{"name": {"first": "Tom", "last": "Anderson"}, "age": 37, "children": ["Sara", "Alex", "Jack"], "friends": [{"first": "James", "last": "Murphy"}, {"first": "Roger", "last": "Craig"}]}` //获取数据 name1 := gjson.Get(jsonStr, "name") //默认返回的是gjson.Result类型,如果是直接打印,可直接使用,若是需进一步操作,建立转换成对应类型 name2 := gjson.Get(jsonStr, "name").String() //从 jsonStr 中获取 "name" 字段的值,然后通过调用 .String() 方法,将获取到的值转换为字符串类型,如果 "name" 字段的值不是字符串类型,它会被转换为字符串 name3 := gjson.Get(jsonStr, "name").Str //也是从 jsonStr 中获取 "name" 字段的值,但是是直接获取该字段的值,没有进行类型转换,如果"name"字段的值不是字符串类型,则将保持原来的类型 //如果确定 "name" 字段的值一定是字符串类型,那么使用 .Str 是更简洁的方式。如果不确定 "name" 字段的值是什么类型,或者想要确保它是一个字符串类型,那么使用 .String() 进行显式转换是更安全的选择。 fmt.Printf("值类型:%T,值:%v\n", name1, name1) fmt.Printf("值类型:%T,值:%v\n", name2, name2) fmt.Printf("值类型:%T,值:%v\n", name3, name3) //无法输出值是因为name" 是一个嵌套的 JSON 对象,而不是一个字符串 first := gjson.Get(jsonStr, "name.first").Str //需要进一步获取值 fmt.Printf("值类型:%T,值:%v\n", first, first) }
输出结果:
值类型:gjson.Result,值:{"first": "Tom", "last": "Anderson"} 值类型:string,值:{"first": "Tom", "last": "Anderson"} 值类型:string,值: 值类型:string,值:Tom
2、类型转换
方法 | 描述 |
String() | 尝试将此值转换为string |
Int() | 尝试将此值转换为int64 |
Uint64() | 尝试将此值转换为uint64 |
Float64() | 尝试将此值转换为float64 |
Bool() | 尝试将此值转换为布尔型 |
3、键路径
键路径实际上是以.
分隔的一系列键。gjson
支持在键中包含通配符*
和?
,*
匹配任意多个字符,?
匹配单个字符,例如ca*
可以匹配cat/cate/cake
等以ca
开头的键,ca?
只能匹配cat/cap
等以ca
开头且后面只有一个字符的键。
数组使用键名 + .
+ 索引(索引从 0 开始)的方式读取元素,如果键pets
对应的值是一个数组,那么pets.0
读取数组的第一个元素,pets.1
读取第二个元素。
数组长度使用**键名 + .
+ #
**获取,例如pets.#
返回数组pets
的长度。
如果键名中出现.
,那么需要使用\
进行转义
例(使用上面的json字符串):
//设置json字符串 jsonStr := `{"name": {"first": "Tom", "last": "Anderson"}, "age": 37, "children": ["Sara", "Alex", "Jack"], "friends": [{"first": "James", "last": "Murphy"}, {"first": "Roger", "last": "Craig"}]}` //获取数据 fmt.Println("name.last:", gjson.Get(jsonStr, "name.last")) fmt.Println("age:", gjson.Get(jsonStr, "age")) fmt.Println("children:", gjson.Get(jsonStr, "children")) fmt.Println("children.#:", gjson.Get(jsonStr, "children.#")) //返回数组的长度 fmt.Println("children.1:", gjson.Get(jsonStr, "children.1")) //读取数组下标为1的元素值(注意下标从0开始) fmt.Println("child*.2:", gjson.Get(jsonStr, "child*.2")) //*匹配,再读取下标为2的元素值 fmt.Println("c?ildren.0:", gjson.Get(jsonStr, "c?ildren.0")) //也是匹配,不过只匹配一个字符,再读取下标为0的元素值 fmt.Println("friends.#.first:", gjson.Get(jsonStr, "friends.#.first")) //如果数组#后还有内容,则以后面的路径读取数组中的每个元素,返回一个新的数组。所以该查询返回的数组所有friends的first字段组成 fmt.Println("friends.1.first:", gjson.Get(jsonStr, "friends.1.first")) //读取friends第 2 个元素的last字段
输出结果:
name.last: Anderson age: 37 children: ["Sara", "Alex", "Jack"] children.#: 3 children.1: Alex child*.2: Jack c?ildren.0: Sara friends.#.first: ["James","Roger"] friends.1.first: Roger
3.1 数组
对于数组,gjson
还支持按条件查询元素,#(条件)
返回第一个满足条件的元素,#(条件)#
返回所有满足条件的元素。括号内的条件可以有==
、!=
、<
、<=
、>
、>=
,还有简单的模式匹配%
(符合某个模式),!%
(不符合某个模式):
package main import ( "fmt" "github.com/tidwall/gjson" ) func main() { //设置json字符串 var jsonStr = `{"name": {"first": "Tom", "last": "Anderson"}, "age": 37, "children": ["Sara", "Alex", "Jack"], "fav.movie": "Dear 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":{"first":"Tom", "last": "Anderson"}, // "age": 37, // "children": ["Sara", "Alex", "Jack"], //"fav.movie": "Dear 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"]} // ] //} //输出数据 fmt.Println(gjson.Get(jsonStr, `friends.#(last="Murphy").first`)) //返回数组friends中第一个last为Murphy的元素;.first表示取出该元素的first字段返回 fmt.Println(gjson.Get(jsonStr, `friends.#(last="Murphy")#.first`)) //返回数组friends中所有的last为Murphy的元素,然后读取它们的first字段放在一个数组中返回 fmt.Println(gjson.Get(jsonStr, "friends.#(age>37)#.last")) //返回数组friends中所有年龄大于 45 的元素,然后读取它们的last字段返回 fmt.Println(gjson.Get(jsonStr, `friends.#(first%"D*").last`)) //返回数组friends中第一个first字段满足模式D*的元素,取出其last字段返回 fmt.Println(gjson.Get(jsonStr, `friends.#(first!%"D*").last`)) //返回数组friends中第一个first字段**不**满足模式D*的元素,读取其last`字段返回 fmt.Println(gjson.Get(jsonStr, `friends.#(nets.#(=="fb"))#.first`)) //这是个嵌套条件,friends.#(nets.#(=="fb"))#返回数组friends的元素的nets字段中有fb的所有元素,然后取出first字段返回 }
输出结果:
Dale ["Dale","Jane"] ["Murphy","Craig","Murphy"] Murphy Craig ["Dale","Roger"]
4、 一次获取多个值
调用gjson.Get()
一次只能读取一个值,多次调用又比较麻烦,gjson
提供了GetMany()
可以一次读取多个值,返回一个数组[]gjson.Result
。
//获取数据,使用3里面的字符串 results := gjson.GetMany(jsonStr, "name", "age", "children.#", "friends.#.first") for _, result := range results { fmt.Println(result) } //输出结果 // {"first": "Tom", "last": "Anderson"} // 37 // 3 // ["Dale","Roger","Jane"]
5、校验json
调用gjson.Get()
时,gjson
假设我们传入的 JSON 串是合法的。如果 JSON 非法也不会panic
,这时会返回不确定的结果
gjson.Valid()
检测 JSON 串是否合法:
if !gjson.Valid(json) { fmt.Println("error") } else { fmt.Println("ok") }
6、遍历
gjson.Get()
方法返回一个gjson.Result
类型的对象,json.Result
提供了ForEach()
方法用于遍历。该方法接受一个类型为func (key, value gjson.Result) bool
的回调函数。遍历对象时key
和value
分别为对象的键和值;遍历数组时,value
为数组元素,key
为空(不是索引)。回调返回false
时,遍历停止。
results := gjson.Get(jsonStr, "friends") //获取初始数据,3里面的字符串 results.ForEach(func(k, result gjson.Result) bool { //遍历,一般不需要k,可用_忽略 first := gjson.Get(result.Raw, "first") //可以再次根据键路径获取更为详细的数据 fmt.Printf("k:%v,v:%v\n", k, results) //输出键值 fmt.Println(first) //输出friends数组里的first元素值 return true })
输出结果:
k:0,v:[{"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"]}] Dale k:1,v:[{"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"]}] Roger k:2,v:[{"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"]}] Jane PS D:\Users\W9010315\GolandProjects\test> go run .\gjson.go k:0,v:[{"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"]}] Dale k:1,v:[{"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"]}] Roger k:2,v:[{"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"]}] Jane
本文参考:https://darjun.github.io/2020/03/22/godailylib/gjson/
标签:jsonStr,gjson,--,age,Go,last,nets,first From: https://www.cnblogs.com/Xinenhui/p/17879819.html