Go语言(使用)——解析json文件

要用到的包

  • gojsonq
  • 获得方法:
go get github.com/thedevsaddam/gojsonq

用来解析的数据

//在 comment.json 文件里
{"CommentsCount1":
  [
    {
      "SkuId":100003814753,
      "ProductId":100003814753,
      "CommentCountStr":"5万+",
      "GoodRate":0.98,
      "GeneralRate":0.015,
      "PoorRate":0.005
    }
  ],
  "CommentsCount2":
  [
    {
      "SkuId":100005671234,
      "ProductId":100005671234,
      "CommentCountStr":"3万+",
      "GoodRate":0.97,
      "GeneralRate":0.02,
      "PoorRate":0.01
    }
  ]
}

相关数据结构

  • JSONQ 的结构。
type JSONQ struct {
	option           option               // contains options for JSONQ
	queryMap         map[string]QueryFunc // contains query functions
	node             string               // contains node name
	raw              json.RawMessage      // raw message from source (reader, string or file)
	rootJSONContent  interface{}          // original decoded json data
	jsonContent      interface{}          // copy of original decoded json data for further processing
	queryIndex       int                  // contains number of orWhere query call
	queries          [][]query            // nested queries
	attributes       []string             // select attributes that will be available in final resuls
	offsetRecords    int                  // number of records that will be skipped in final result
	limitRecords     int                  // number of records that will be available in final result
	distinctProperty string               // contain the distinct attribute name
	errors           []error              // contains all the errors when processing
}
  • option 的结构。
// option describes type for providing configuration options to JSONQ
type option struct {
	decoder   Decoder
	separator string
}
  • RawMessage 实际上就是 []byte。
// RawMessage is a raw encoded JSON value.
// It implements Marshaler and Unmarshaler and can
// be used to delay JSON decoding or precompute a JSON encoding.
type RawMessage []byte
  • query 的结构。
// query describes a query
type query struct {
	key, operator string
	value         interface{}
}

一步一步来分析

读取文件加载数据
import (
	"fmt"
	"github.com/thedevsaddam/gojsonq"
)
  1. 加载文件
jsonq := gojsonq.New()
//返回 JSONQ 指针,jsonq --> *JSONQ
  • New() 函数的代码如下所示:
// New returns a new instance of JSONQ,返回一个 JSONQ 实例
func New(options ...OptionFunc) *JSONQ {
	jq := &JSONQ{
		queryMap: defaultQueries(),
		option: option{
			decoder:   &DefaultDecoder{},
			separator: defaultSeparator,
		},
	}
	for _, option := range options {
		if err := option(jq); err != nil {
			jq.addError(err)
		}
	}
	return jq
}
  1. 定位到 json 文本的某个节点。
node := json.From("CommentsCount1")
  • From(node string) 方法的代码如下所示:
// From seeks the json content to provided node. e.g: "users.[0]"  or "users.[0].name"
func (j *JSONQ) From(node string) *JSONQ {
	j.node = node
	v, err := getNestedValue(j.jsonContent, node, j.option.separator)
	if err != nil {
		j.addError(err)
	}
	j.jsonContent = v
	return j
}
  1. 从查询到的节点中选择属性。
attrVal := node.Select("CommentCountStr")
  • Select(properties …string) 的代码如下所示:
// Select use for selection of the properties from query result
func (j *JSONQ) Select(properties ...string) *JSONQ {
	j.attributes = append(j.attributes, properties...)
	return j
}
//实际上,它就是把你要查找的属性添加到 attributes 属性切片里
  1. 上一步已经决定查找哪些属性的值了,那么现在就让我们来查看属性值是什么吧。
val := attrVal.Get()
  • Get() 的代码有点复杂,但是我们只要搞清楚它返回的是个什么类型的值就好了,通过源码我们发现,它返回的是个 interface{},更进一步的,我们输出上面 val,查看它的值是什么。
[map[CommentCountStr:5万+]]
  • 我们发现,首先它是一个切片,然后切片里存储的数据类型是 map,那么我们现在可以利用类型断言来处理我们获得最终结果。
//一步一步来,不着急
commentCountStrInterSlice := val.([]interface{})
commentCountStrMap := commentCountStrInterSlice[0].(map[string]interface{})
commentCountStr := commentCountStrMap["CommentCountStr"].(string)
  • 我也可以一步整到位,套娃呗。
commentCountStr := (val.([]interface{}))[0].(map[string]interface{})["CommentCountStr"].(string)
读取字符串加载数据
  • 其实这一节与上一节唯一不同的地方就是数据不是从文件里加载而来,而是从字符串加载,其他步骤都一样,但是额外还想说的就是,前面一节我们只介绍了如何查找一个属性的值是多少,我们其实还可以一次性查看多个属性的值分别是多少。
  1. 首先从字符串里加载数据。
jsonText := `
{"CommentsCount1":
  [
    {
      "SkuId":100003814753,
      "ProductId":100003814753,
      "CommentCountStr":"5万+",
      "GoodRate":0.98,
      "GeneralRate":0.015,
      "PoorRate":0.005
    }
  ],
  "CommentsCount2":
  [
    {
      "SkuId":100005671234,
      "ProductId":100005671234,
      "CommentCountStr":"3万+",
      "GoodRate":0.97,
      "GeneralRate":0.02,
      "PoorRate":0.01
    }
  ]
}`
jsonq := gojsonq.New().FromString(jsonText)
  1. 定位到某个节点处。
node := jsonq.From("CommentsCount1")
  1. 选择属性。
//这次我们一次性多选几个属性
attrVal:= node.Select("CommentCountStr", "GoodRate", "GeneralRate", "PoorRate")
  • 让我们看看此时 attrVal 是多少。
[map[CommentCountStr:5万+ GeneralRate:0.015 GoodRate:0.98 PoorRate:0.005]]
  1. 获得属性值。
vals := attrVal.Get()
  1. 类型断言。
valSlice := vals.([]interface{})
commentCountStr := valSlice[0].(map[string]interface{})["CommentCountStr"].(string)
goodRate := valSlice[0].(map[string]interface{})["GoodRate"].(float64)
generalRate := valSlice[0].(map[string]interface{})["GeneralRate"].(float64)
poorRate := valSlice[0].(map[string]interface{})["PoorRate"].(float64)
  • 最后输出,查看一下。
fmt.Println(commentCountStr, goodRate, generalRate, poorRate)

输出结果如下:

5万+ 0.98 0.015 0.005
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wuxy_Fansj_Forever

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值