duanao4503 2015-12-01 07:41
浏览 156
已采纳

如何在Go中将嵌套的JSON解析为结构?

How can I map a nested JSON to a nested Struct like this:

type ChildStruct1 struct {
    key3,
    key4,string
}
type ChildStruct2 struct {
    key4,
    key5,string
}

type MainStruct struct {
    key1,
    key2,string
    childStruct1 ChildStruct1
    childStruct2 ChildStruct1
}

Input JSON:

{
  key1: val1,
  key2: val2,
  chilDStruct1 : {
                     key3: val3,
                     key4: val4,
                }
  chilDStruct2 : {
                     key5: val5,
                     key6: val6,
                }
}

How can this be mapped. I have used jsonMapper in Java but not sure how to do it here. I tried this but this is not working:

var data MainStruct
    file, err := ioutil.ReadFile("jsonData.json")
    if err != nil {
        log.Fatal(err)
    }
    err = json.Unmarshal(file, &data)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(data.key1)

I tried this also:

u := &MainStruct{}
file, err := ioutil.ReadFile("jsonData.json")
if err != nil {
    log.Fatal(err)
}
err = json.Unmarshal([]byte(file), u)
if err != nil {
    log.Fatal(err)
}
fmt.Println(u.key1)

But output is always 0.

  • 写回答

1条回答 默认 最新

  • doutu9810 2015-12-01 08:00
    关注

    You have quite some errors in your example (both in JSON text and source code). Let's fix them.

    JSON text

    First your JSON is not valid. Try this instead of yours:

    {
        "key1": "val1",
        "key2": "val2",
        "childStruct1" : {
            "key3": "val3",
            "key4": "val4"
        },
        "childStruct2" : {
            "key5": "val5",
            "key6": "val6"
        }
    }
    

    Go type definitions

    Second, your Go source defining your struct types has syntax errors.

    Third, you have to export struct fields in order so the json package can set their values. Try this instead of yours:

    type ChildStruct1 struct {
        Key3 string
        Key4 string
    }
    
    type ChildStruct2 struct {
        Key4 string
        Key5 string
    }
    
    type MainStruct struct {
        Key1         string
        Key2         string
        ChildStruct1 ChildStruct1
        ChildStruct2 ChildStruct2
    }
    

    Code to parse the JSON text

    And now on to the code to parse the JSON text. You can read the whole file into memory using ioutil.ReadFile(), but often it is more efficient to not read the whole file but to "stream" it to a decoder (using the file as the input).

    os.Open() returns a *File. It is not a []byte, but it implements io.Reader. So you can't pass it to json.Unmarshal(). Instead create a json.Decoder using json.NewDecoder() which accepts an io.Reader, so you can pass the opened file. And don't forget to close the opened file using File.Close(), best to close it as a deferred statement (if opening it succeeds).

    f, err := os.Open("jsonData.json")
    if err != nil {
        log.Panic(err)
    }
    defer f.Close()
    
    var data MainStruct
    err = json.NewDecoder(f).Decode(&data)
    if err != nil {
        log.Panic(err)
    }
    fmt.Println(data.Key1)
    fmt.Printf("%+v", data)
    

    (Note that I used log.Panic() instead of log.Fatal() as the latter calls os.Exit() and hence our deferred function would not be called.)

    Output:

    val1
    {Key1:val1 Key2:val2 ChildStruct1:{Key3:val3 Key4:val4} ChildStruct2:{Key4: Key5:val5}}
    

    Modified version for the Go Playground

    Here is a modified version that parses the JSON text from a constant defined in the source code, try it on the Go Playground:

    var data MainStruct
    err := json.Unmarshal([]byte(input), &data)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(data.Key1)
    fmt.Printf("%+v", data)
    

    Final notes

    Keys in the JSON text start with lowercase letters, struct field names in Go start with uppercase letters (needed in order to be exported), but the json package is "clever" enough to match them. Should you use something different, you could use tags to specify how a struct field can be found in the json, e.g.

    type ChildStruct1 struct {
        Key3 string `json:"myKey3"`
        Key4 string `json:"myKey4"`
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码