首页 > 其他分享 >gjson - Golang 解析 JSON

gjson - Golang 解析 JSON

时间:2023-06-20 11:03:48浏览次数:48  
标签:gjson string Get json Golang JSON score data



文章目录

  • 简介
  • 主要类型
  • Type
  • Result
  • 方法
  • gjson
  • result
  • Path
  • 修饰符
  • 示例
  • 介绍
  • 自定义
  • 备用



简介


主要类型

Type

  • 说明
说明: 解析的数据类型(实际是int类型)
功能: 用于解析和输出时做判断
包括:
- True
- False
- String
- JSON
- Number
- Null
功能: 只有一个String()方法, 返回对应类型的字符串(如JSON类型返回"JSON", 未定义的类型返回"")
  • 实现
// Type is Result type
type Type int

const (
	// Null is a null json value
	Null Type = iota
	// False is a json false boolean
	False
	// Number is json number
	Number
	// String is a json string
	String
	// True is a json true boolean
	True
	// JSON is a raw block of JSON
	JSON
)

Result

  • 说明
说明: 用户存放解析的结果
  • 实现
// Result represents a json value that is returned from Get().
type Result struct {
	// Type is the json type
	Type Type
	// Raw is the raw json
	Raw string
	// Str is the json string
	Str string
	// Num is the json number
	Num float64
	// Index of raw value in original json, zero means index unknown
	Index int
	// Indexes of all the elements that match on a path containing the '#'
	// query character.
	Indexes []int
}

方法

gjson

  • 验证JSON是否合法, 返回bool
data1 := `{"data": {"msg": "test"}}`
data2 := []byte(`{"data": {"msg": "test"}}`)

// 参数类型为string
gjson.Valid(data1)

// 参数类型为[]byte
gjson.ValidBytes(data2)
  • 解析完整JSON串, 返回Result
// 参数类型为string
gjson.Parse(data1)

// 参数类型为[]byte
gjson.ParseBytes(data2)
  • 解析JSON串的指定path, 返回Result
// 参数类型为string
gjson.Get(data1, "data")

// 参数类型为[]byte
gjson.GetBytes(data2, "data")
  • 解析JSON串的多个指定path, 返回[]Result
// 参数类型为string
gjson.GetMany(data1, "data", "data.msg")

// 参数类型为[]byte
gjson.GetManyBytes(data2, "data", "data.msg")
  • 修饰符
// ModifierExists 验证修饰符方法是否存在
// 实际只有第一个参数有意义, 参数func可以直接传空
gjson.ModifierExists("pretty", nil)

// AddModifier 添加修饰符方法
gjson.AddModifier("yky", func(json, arg string) string {
    return "123"
})
  • 逐行处理
data3 := `{"data": {"msg": "test1"}}
{"data": {"msg": "test2"}}
{"data": {"msg": "test3"}}`

gjson.ForEachLine(data3, func(line gjson.Result) bool {
        // 处理代码段, 可以在外边单独定义
        fmt.Println("data.msg")
        return true
	})

result

  • 基于类型的方法
// 输出类型
gjson.Get(data, "data").Type.String

// 返回json原始结果(即key冒号后边的所有内容)
// "k":[1,2,3] --> [1,2,3]
// "k":"\"abc\"" --> "\"abc\""
gjson.Get(data, "data").Raw

// String类型返回字符串, 不是返回""
gjson.Get(data, "data").Str

// 数字类型返回int64, 不是返回0
gjson.Get(data, "data").Num
  • 获取对应类型结果
// 返回对应类型
gjson.Get(data, "data").Int()
gjson.Get(data, "data").Uint()
gjson.Get(data, "data").Float()
gjson.Get(data, "data").String()
gjson.Get(data, "data").Bool()
gjson.Get(data, "data").Time()

// --> map[string]Result
gjson.Get(data, "data").Map()
// --> []Result
gjson.Get(data, "data").Array()
// --> interface{}
gjson.Get(data, "data").Value()
  • 获取判断结果, 返回bool
// result.type == JSON && len(result.raw) > 0 && result.raw[0] == "{"
gjson.Get(data1, "data").IsObject()

// result.type == JSON && len(result.raw) > 0 && result.raw[0] == "["
gjson.Get(data1, "data").IsArray()

// result.type == True || result.type == False
gjson.Get(data1, "data").IsBool()

// result.Type != Null || len(result.Raw) != 0
gjson.Get(data1, "data").Exists()
  • 继续查询
gjson.Get(data1, "data").Get("key")
  • 遍历查询
gjson.Get(data, "data").ForEach(func(key, value gjson.Result) bool {

    // 当data取出的是array时, key为index
    // 当data取出的是map时, key为key
    
    // 根据处理结果返回bool
    return true
})

Path

  • 获取长度(仅对array生效)
data := `{"k": [1, 2, 3]}`
gjson.Get(data, "k.#").Int()
  • 遍历array
data := `{"k":[{"foo":11},{"foo":2},{"foo":3}]}`
gjson.Get(data, "k.#.foo").Int()
  • 根据索引取值
data := `{"k":[{"foo":11},{"foo":2},{"foo":3}]}`
gjson.Get(data, "k.1.foo").Int()
  • 模糊匹配(只返回第一个找到的结果)
data := `{"aa":100, "a22a":200, "a333a":300}`

// * 匹配0~n个任意字符
gjson.Get(data, "a*a").Int()

// ? 匹配1个任意字符
gjson.Get(data, "a?a").Int()
  • 条件判断
data := `{"data": [
    {"lesson": "english", "score": 10},
    {"lesson": "math", "score": 90},
    {"lesson": "chinese", "score": 100},
]}`

// #... 返回匹配的第一个结果
gjson.Get(data, "data.#(score>20).lesson")

// #...# 返回匹配的所有结果
gjson.Get(data, "data.#(score>20).lesson")

// 支持判断条件, ==, !=, <, <=, >,>=, %(like) 和 !%(not like)
gjson.Get(data, `data.#(lesson%"*e*")#.score`)
  • 多层条件判断
data := `{"data": [
    {"lesson":"math", "score": [100, 100, 100]},
    {"lesson":"chinese", "score": [60, 30, 90]},
    {"lesson":"english", "score": [80, 40, 100]}
]}`

// 查询score小于60的lesson
gjson.Get(data, "data.#(score.#(<60))#.lesson")

// path推导过程
// data.#()#.lesson --> 由于最后要输出lesson的内容,所以最外层格式是这样的
// data.#(score.#())#.lesson --> 内层需要获取score中的值做判断, (需求是有小于60的分数就返回, 所以是#...)
// data.#(socre.#(<60))#.lesson --> 判断条件为小于60,而且格式为array,所以不需要写keyName, 直接写(<60)即可

修饰符

示例

data := `{"data": [1, [2, [3, 4]] ]}`

// gjson 调用需要带path
gjson.Get(data, `data|@flatten:{"deep":true}|@reverse`)

// result 调用直接指定修饰符和参数即可
gjson.Get(data, `data`).Get(`@flatten:{"deep":true}|@reverse`)

// 先修饰后取值(array填索引, map填key)
gjson.Get(data, `data`).Get(`@flatten:{"deep":true}|@reverse|0`)

介绍

// 具体修饰功能的参数可以进源码查看

var modifiers = map[string]func(json, arg string) string{
	"pretty":  modPretty,  // 增加缩进
	"ugly":    modUgly,  // 去掉所有空格
	"reverse": modReverse,  // 反序array
	"this":    modThis,  // 返回当前(不做处理)
    "flatten": modFlatten,  // 展开array(只展开一层), {"deep":true} --> 全部展开
    "join":    modJoin,  // 合并[{},{}]的每对kv
	"valid":   modValid,  // 判断是否合法, 合法返回json, 不合法返回""
	"keys":    modKeys,  // 返回map的所有key
	"values":  modValues,  // 返回map的所有value
	"tostr":   modToStr,  // 转raw字符串
	"fromstr": modFromStr,  // 转普通字符串
	"group":   modGroup,
}

自定义

  • 参考 gjson.AddModifier

备用

  • 类反序列化处理
data := []byte(`{"name":"Aki", "age":25, "num":"1231231234", "score": {"english": 100, "math": 99}}`)
rs := gjson.GetManyBytes(data, "name", "age", "num", "score")
score := map[string]int64{
	"english": rs[3].Get("english").Int(),
	"math":    rs[3].Get("math").Int(),
}
stu1 := Stu{
	Name:  rs[0].String(),
	Age:   rs[1].Int(),
	Num:   rs[2].String(),
	Score: score,
}
  • 没搞明白的
gjson.AppendJSONString(data2, data1)

gjson.Get(data, "data").Path()
gjson.Get(data, "data").Paths()

gjson.Get(data, "data").Less()


标签:gjson,string,Get,json,Golang,JSON,score,data
From: https://blog.51cto.com/u_16165803/6521274

相关文章

  • Golang - kafka 的使用
    producerpackagemainimport( "fmt" "github.com/Shopify/sarama" "log" "strconv")const( BROKER="ip:port" TOPIC="xx")//sendMsg发送到kfkfuncsendMsg(clientsarama.SyncProducer,ms......
  • Golang - net/http 笔记
    Serverpackagemainimport( "fmt" "log" "net/http")//模拟实现Handler接口typeBarstruct{}func(bBar)ServeHTTP(whttp.ResponseWriter,req*http.Request){ tgt:=req.URL.Query().Get("name") fmt.Fprintf(w,......
  • Golang - 日志
    官方Log包方法输出到logger.out:log.Print(),log.Printf(),log.Println()输出到logger.out,再执行os.Exit(1):log.Fatal(),log.Fatalln(),log.Fatalf()输出到logger.out,再执行panic():log.Panic(),log.Panicln(),log.Panicf()logger结构体typeLoggerstruc......
  • Golang - Structs 包的使用
    packagemain////主要用于struct转map//还可以判断结构体是否有空属性等功能//import( "fmt" "github.com/fatih/structs")//struct-->maptypeStustruct{ Namestring Ageint}funcmain(){ //创建一个Age属性为空的struct实例 u1:=Stu{......
  • postgresql json取值为何这么慢?
    一、缘起慢sql分析,总行数80w+,通过监控分析慢SQL,某个查询耗时超1s。比较特殊的是:其中有个字段info是jsonb类型,写法:info::json->'length'aslength同样的查询条件查这个字段和不查这个字段相差3.3倍那看来就是json取值拖垮了查询的性能。取jsonb中的字段有多种取法(如下),那......
  • 利用react-json-view最JSON数据进行渲染
    1.安装npminstall--savereact-json-view2.使用importReactJsonfrom"react-json-view";constA=()=>{letsrc={"content-length":"675","x-b3-parentspanid":"06c634eea567252a",&quo......
  • Mongodb 为什么提起处理JSON 就是MOGNODB 的,因为我没得选
    提到JSON的数据处理,大部分人想到的一定是MONGODB,如果不是可以自己好好的反思一下,自己的数据库餐盘是不是缺少MOGNODB这道硬菜,最近也有人问我一个问题,关于使用mongodb的原因是什么,我回答的比较简单,但是我更原因用这样的方式来回答这个问题。提到MOGNODB的特长,必须提到JSON,在数......
  • vite+vue3项目中使用 lottie 动画,如何在 template 中直接使用本地 json 文件路径
    安装lottie-webyarnaddlottie-web封装 lottie组件<template><divref="animation":style="{width,height}"></div></template><script>import{defineComponent,ref,onMounted}from'vue'......
  • 关于ASP.NET.CORE中的Failed to read parameter "string param" from the request bod
    先上报错信息Microsoft.AspNetCore.Http.BadHttpRequestException:Failedtoreadparameter"stringparam"fromtherequestbodyasJSON.--->System.Text.Json.JsonException:'s'isaninvalidstartofavalue.Path:$|LineNumber:0|By......
  • 关于前后端JSON解析差异问题与思考
    本文主要总结了作者在一次涉及流程表单的需求发布中遇到的问题及思考总结。 一、问题回顾在一次涉及流程表单的需求发布时,由于表单设计的改动,需要在历史工单中的一个json字段增加一个属性,效果示意如下:[{"key1":"value1"}]->[{"key1":"value1","key2":"value2"}]......