dongzhuang6177 2018-07-16 20:19 采纳率: 100%
浏览 73
已采纳

在Go Lang中使用深度嵌套的JSON

I have what I would consider a very messy block of JSON, and I want to read and modify two values that are deeply nested within (denoted: I want this!) using Go. Due to the server that I am sending it to, I cannot change the label names. What makes it especially difficult for me is that parents have multiple children which are also nested, and since there are so many "value" labels I don't know how to specify which "value" child thatI want to enter.

I got the values in Bash very quickly using this

jq ' .value[0].value[1].value[0].value[1].value[0].value="'"$one"'" | '\ '
.value[0].value[1].value[0].value[1].value[1].value="'"$two"'"'

I tried a format like this in Go initially, but could not get it working because of the issue where children are all named "value" and I want to go into one other than the first. Unfortunately none of those magic JSON to Go struct were able to handle all of the nesting either.

type Bar struct {
    Value struct { // Value[0]
        Value struct {  // Value[1]
            Value struct { // Value[0]
                Value struct { // Value[1]
                    Value struct { // Value[1] or Value[2]
                    }}}}}}

This code converts the JSON into a more struct/map friendly form, and prints the whole thing.

var foo interface{}
err := json.Unmarshal(blob, &foo)
if err != nil {
    fmt.Println("error:", err)
}

m := foo.(map[string]interface{})

// print all
fmt.Println("Loop: ", m)
for k, v := range m {
    fmt.Printf("%v : %v", k, v)
}

Here is the JSON that I am storing as a variable

var blob = []byte(`{
"tag": "1",
"value": [{
        "tag": "2",
        "value": [{
                "tag": "3",
                "value": [{
                        "tag": "4",
                        "type": "x",
                        "value": "x"
                    }, {
                        "tag": "5",
                        "type": "x",
                        "value": "x"
                    }
                ]
            }, {
                "tag": "6",
                "value": [{
                        "tag": "7",
                        "value": [{
                                "tag": "8",
                                "type": "x",
                                "value": "x"
                            }, {
                                "tag": "9",
                                "value": [{
                                        "tag": "10",
                                        "type": "x",
                                        "value": "I want this!"
                                    }, {
                                        "tag": "11",
                                        "type": "Thanks for the help mate!",
                                        "value": "I want this!"
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }, {
                "tag": "12",
                "type": "x",
                "value": "x"
            }
        ]
    }, {
        "tag": "13",
        "value": [{
                "tag": "14",
                "type": "x",
                "value": "x"
            }, {
                "tag": "15",
                "value": [{
                        "tag": "16",
                        "value": [{
                                "tag": "17",
                                "type": "x",
                                "value": "x"
                            }
                        ]
                    }
                ]
            }
        ]
    }
]
}`)

I would appreciate any help or advice that you could give me.

  • 写回答

1条回答 默认 最新

  • duancong2965 2018-07-16 20:38
    关注

    Your initial attempt didn't work because you used structs where you need a slice of struct (Value []struct{...}). But that won't work either, because in some cases the values are slices and in some cases they're strings, which encoding/json does not like. Your best bet is one of two options: raw text manipulation, which will probably be quicker but more fragile and error-prone, or decoding as in your second example into a map[string]interface{} and doing some gnarly type assertions:

    var foo map[string]interface{}
    err := json.Unmarshal(blob, &foo)
    if err != nil {
        fmt.Println("error:", err)
    }
    
    foo["value"].([]interface{})[0].(map[string]interface{})["value"].([]interface{})[1].(map[string]interface{})["value"].([]interface{})[0].(map[string]interface{})["value"].([]interface{})[1].(map[string]interface{})["value"].([]interface{})[0].(map[string]interface{})["value"]
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题
  • ¥15 (标签-Python|关键词-socket)
  • ¥15 keil里为什么main.c定义的函数在it.c调用不了