将新的键值对添加到JSON对象

时间:2018-08-11 01:25:59

标签: json go

我正在连接到一个提供相当大的json有效负载的API。我需要向根对象添加键和值。一旦从包“ net / http”中执行ioutil.Readall,JSON就是一个字节数组。

我的目标是仅添加到结构中并继续前进。例如,以下内容与我正在执行的操作非常相似:https://tutorialedge.net/golang/consuming-restful-api-with-go/

那么如何简单地将另一个元素(键:值)添加到JSON结构中?

5 个答案:

答案 0 :(得分:5)

如果您要做的只是向根对象添加键和值并生成新的JSON,并且您不关心将数据存储在结构中,则可以将其解编为map[string]interface{},然后添加值,然后再次编组:

var m map[string]interface{}
err := json.Unmarshal(data, &m)
m["new_key"] = newValue
newData, err := json.Marshal(m)

(我不检查错误,但是您应该这样做。)查看https://golang.org/pkg/encoding/json/,以获取有关如何在Go中处理JSON的更多信息。

答案 1 :(得分:2)

由于您有字节数据,因此需要使用json.Marshal对其进行解析并将结果存储在具有json结构的变量中。

然后,要添加新的键值对,可以使用键及其数据类型定义新的struct

var variable type1
// Unmarshal the byte data in a variable
json.Unmarshall(data, &variable)
// to add a new key value you can define a new type
type type2 struct {
type1
key type
}
// and you can add
variable2 := type2{variable, newValueToAdd}

答案 2 :(得分:2)

虽然反序列化和重新序列化是更“正确”的方法,但是仅在根上添加一个值可能会过大,这可以通过简单的字符串操作(确实是字节片操作)来完成,但是语义相似,并且可以说是有道理的更容易):

data := []byte(`{"foo": 1, "bar": true}`)
ins := []byte(`, "baz": "hello"`)    // Note the leading comma.
closingBraceIdx := bytes.LastIndexByte(data, '}')
data = append(data[:closingBraceIdx], ins...)
data = append(data, '}')

这更容易出错,因为它完全不了解JSON语法,但是对于大多数情况和大型JSON文档而言,它足够安全,比解析,插入和重新序列化更为有效。

游乐场示例:https://play.golang.org/p/h8kL4Zzp7rq

答案 3 :(得分:2)

以下是如何以有效的方式执行此操作,同时保留原始 JSON 中的键顺序。这个想法是使用 json.RawMessage

// original JSON
bytes := []byte(`{"name": "Adele", "age": 24}`)

// let's try to add the kv pair "country": "USA" to it
type Person struct {
    Bio     json.RawMessage `json:"bio"`
    Country string          `json:"country"`
}

p := Person{
    Bio:     json.RawMessage(bytes), 
    Country: "USA",
}

// ignoring error for brevity
modifiedBytes, _ := json.Marshal(p)
fmt.Println(string(modifiedBytes))

输出:

{"bio":{"name":"Adele","age":24},"country":"USA"}

您可以看到保留了原始 JSON 的顺序,如果您将 JSON 编组为 map[string]interface{},则不会出现这种情况。当您处理巨大的 JSON 时,这也更有效,因为不涉及反射。

完整代码 - https://play.golang.org/p/3hAPVbrAo_w

答案 4 :(得分:1)

如果要将json字节的键值添加到新的json对象,则可以使用json.RawMessage。

    type Res struct {
        Data interface{}
        Message string
    }

    var row  json.RawMessage
    row = []byte(`{"Name":"xxx","Sex":1}`)
    res := Res{Data:row,Message:"user"}

   
    resBytes ,err := json.Marshal(res)
    println(string(resBytes))
    //print result:"Data":{"Name":"xxx","Sex":1},"Message":"user"}