drgd73844 2018-07-11 20:38
浏览 104
已采纳

首先在Go中编辑Json,而无需先整理结构

I am having a bit of an issue. So I am writing a tool in go that works with some json files. The way the tool works is the devops member who is using it is supposed to upload their json file into the specified folder within the project and then that json file is used from there to deploy an api in api-gateway (the json is actually a swagger with extensions but that isn't particularly important to my question)

The issue I am having is I need to update ONE line in the json. Each file passed in will be different, but it is guaranteed to have a url in the same spot every time, just due to the nature of the project. I need to update this url in an automated fashion.

Due to the fact the json files are different, setting up hard coded structs and unmarshalling in order to edit is out of the question. The objective is for the devops members to not even have to go into the code, but rather just to deploy their files, which is the reason I was hoping for this to be automated.

So far my research has yielded nothing. It appears that Go only supports editing json if it is first unmarshaled into structs (see Modifying JSON file using Golang). Is there a way to edit without the structs if i know for a fact what I am looking for will always be available within the json, despite each file being different?

This is only my first month using go, so there may be a simple solution. I have seen some mention of scanners from the megajson library, but I cannot seem to get that to work either

{
"paths": {
    "/account": {
        "post": {
            "something": "body",
            "api": {
                "uri": "http://thisiswhereineedtoedit.com"
            }
        }
    }
}

}

  • 写回答

2条回答 默认 最新

  • dongmibeng5885 2018-07-11 21:42
    关注

    Unmarshal to interface{}. Walk down nested objects to find the object with the value to set. Set the value. Marshal back to JSON.

    var root interface{}
    if err := json.Unmarshal(d, &root); err != nil {
        log.Fatal(err)
    }
    
    // Walk down path to target object.
    v := root
    var path = []string{"paths", "/account", "post", "api"}
    for i, k := range path {
        m, ok := v.(map[string]interface{})
        if !ok {
            log.Fatalf("map not found at %s", strings.Join(path[:i+1], ", "))
        }
        v, ok = m[k]
        if !ok {
            log.Fatalf("value not found at %s", strings.Join(path[:i+1], ", "))
        }
    }
    
    // Set value in the target object.
    m, ok := v.(map[string]interface{})
    if !ok {
        log.Fatalf("map not found at %s", strings.Join(path, ", "))
    }
    m["uri"] = "the new URI"
    
    // Marshal back to JSON. Variable d is []byte with the JSON
    d, err := json.Marshal(root)
    if err != nil {
        log.Fatal(err)
    }
    

    Replace calls to log.Fatal with whatever error handling is appropriate for your application.

    playground example

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器