golang:JSON解析值含有[]数组类型的数据,golang解析JIRA search JQL的JSON数据流

有一段数据结构为Jira API 获取的JSON格式数据需要用golang解析,类型如下

{
    "version":"2.0",
    "expand": "schema,names",
    "startAt": 0,
    "maxResults": 2,
    "total": 43,
    "issues": [
    	{
    	"id":"1234",
    	"key":"ascn-234",
    	"fields":{
    		"assignee":{
    			"account":"xiaobo",
    			"email":"xiaobo@mail.com"
    			},
    		"status":{
    			"self": "https://jira.xxx.com/rest/api/2/status/10531",
                "description": "问题启动"
    			},
    		"project":{
    			"id": "12521",
                "key": "PJ",
                "name": "PJ2",
    			},
    		"labels": [
                "11月底必解",
                "红线问题"
                ],
    		"resolution":"finished",
    		"customfield_10861":null,
    		"customfield_10863":null,
    		"customfield_12804": {
                    "self": "https://jira.xxx.com/rest/api/2/customFieldOption/15786",
                    "value": "A",
                    "id": "15786"
                    },
             ...
            }
	    },
	    {
	    	"id":"1235",
	    	"key":"ascn-235",
	    	"fields":{
	    		"assignee":"haitao",
	    		"resolution":"assignee",
	    		"customfield_10876":null,
	    		"customfield_10879":null,
	    		...
	    	}
	    },
	    ....
	]
}

也就是说这段json数据包含的键值对中,值包含 []数组类型,数组内再包含多个对象,对象内的值又包含对象类型。还有存在对象类型还包含更多类型的情况(不过不需要这些数据,可以过滤掉)
由于golang的强类型特征,且Jira customfield_id不同的情况下,在golang中构造相符的结构体是比较困难的。

目前了解到的解决方法有:
1、定义 map[string]interface{},解析到这个结构中,然后类型断言;
2、定义一个类似这个 json 的 struct,解析到这个 struct,可以直接使用在线工具:json 转为 struct;
3、使用 gjson 这样的库:https://github.com/tidwall/gjson 解析;
参考自 https://studygolang.com/topics/3264

方法一:比较灵活,能适应多种类型的键值对
方法二:customfield不固定,样本量较大
方法三:不想使用第三方库

以下给出实现方法(只学了一星期GO):
1、以小化大,先构造出各个对象的结构体

type customfield map[string]interface{}
type assignee map[string]interface{}
type status map[string]interface{}
type labels []string
type field map[string]interface{}
type issue map[string]interface{}

见鬼麻烦死了,直接用第三方库解决(下去好好吸收)
1、第三方库gjson获取所有assignee的账号

package main

import (
	"fmt"
	"io/ioutil"

	"github.com/tidwall/gjson"
)

func main() {
	bytes, err := ioutil.ReadFile("./foo.json")
	if err != nil {
		fmt.Println(err.Error())
	}
	value := gjson.Get(string(bytes), "issues.#.fields.assignee.name")
	println(value.String())
}

//out
["xiaobo","haitao"]

直接导出一个包含的所有assignee账号的数组

上一篇:IDrawingDoc Interface 学习笔记


下一篇:接口的运用