当前位置: 首页 > 工具软件 > gjson > 使用案例 >

gjson - Golang 解析 JSON

都才俊
2023-12-01


简介


主要类型

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()
    
 类似资料: