Golang解析复杂的json

时间:2016-09-19 14:30:05

标签: json parsing go nested

我是golang和json的新手,目前很难从系统中解析出json。

我已经阅读了关于动态json的几篇博文,并尝试了json2GoStructs这样的工具 使用这些工具解析我的json文件只是给了我一个巨大的结构,我发现有点凌乱。我也不知道如何获得我感兴趣的信息。

所以,这是我的问题

  1. 如何获取我感兴趣的信息?
  2. 解析复杂json的最佳方法是什么?
  3. 我只是感兴趣进入以下3个json字段:

    Name
    Guid
    Task -> Property -> Name: Error
    

    我感谢每一个提示,代码段或解释!

    这是我到目前为止所做的(主要来自教程):

    package main
    
    import (
        "encoding/json"
        "fmt"
        "io/ioutil"
    )
    
    func checkErr(err error) {
        if err != nil {
            panic(err)
        }
    }
    
    func readFile(filePath string) []byte {
        data, err := ioutil.ReadFile(filePath)
        checkErr(err)
        return data
    }
    
    func main() {
        path := "/Users/andi/Documents/tmp/wfsJob.json"
        data := readFile(path)
    
        var f interface{}
    
        err := json.Unmarshal(data, &f)
        checkErr(err)
    
        m := f.(map[string]interface{})
    
        for k, v := range m {
            switch vv := v.(type) {
            case string:
                fmt.Println(k, "is string", vv)
            case int:
                fmt.Println(k, "is int", vv)
            case []interface{}:
                fmt.Println(k, "is an array:")
                for i, u := range vv {
                    fmt.Println(i, u)
                }
            default:
                fmt.Println(k, "is of a type I don't know how to handle")
            }
        }
    }
    

2 个答案:

答案 0 :(得分:4)

我可以为您提供this easy way在Golang中使用JSON。使用此工具,您不需要解析整个json文件,并且可以在不使用struct的情况下使用它。

答案 1 :(得分:0)

Gjson是从JSON字符串中提取一些字段的绝佳解决方案。但是,当必须从JSON的不同部分获取许多(超过2个)字段时,它可能会变慢,因为它会在每次Get调用时重新解析JSON。此外,它需要调用gjson.Valid来验证传入的JSON,因为其他方法假定调用者提供有效的JSON。

还有一个替代方案 - fastjson。与gsjon一样,它速度快且API很好。与gjson不同,它验证输入JSON并且在必须从JSON获取许多不相关的字段时工作得更快。以下是从原始问题中获取字段的示例代码:

var p fastjson.Parser
v, err := p.ParseBytes(data)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Name: %s", v.GetStringBytes("Name"))
fmt.Printf("Guid: %s", v.GetStringBytes("Guid"))
fmt.Printf("Error: %s", v.GetStringBytes("Task", "Property", "Name"))