我想在
中使用JSON{ name: "http://example.com", ...}
并将其映射到
{ url: "http://example.com", ...}
我想做这个映射,并能够作为Url回到json。结构相当大,所以可以用一个结构来创建多个结构类型吗?
这是我到目前为止所采用的解决方案:http://play.golang.org/p/wBPbSjkTYF
在看到答案以及我未能准确描述我的用例之后。更新到我试图做的实际映射:
{ "data": { "name": "http://example.com", "key": "value" } }
要:
{ "url": "http://example.com", { "data": "key": "value" } }
答案 0 :(得分:1)
json
包没有任何标签可以让您在Marshal上使用一个字段的键名,在Unmarshal上使用不同的字符。
仍然可以以不同的方式对结构进行制作,但为了做到这一点,你必须实现自己的Marshaller(MarshalJSON函数)。一个工作的例子:
package main
import (
"bytes"
"encoding/json"
"fmt"
)
type Data struct {
Url string `json:"name"`
}
// marshalObject takes a slice of key values
// (should be correctly escaped json strings without "")
// and another slice of interface{} values and marshals
// them into a JSON object string
func marshalObject(keys []string, values []interface{}) ([]byte, error) {
if len(keys) != len(values) {
panic("Different length of keys and values slices")
}
if len(keys) == 0 {
return []byte(`{}`), nil
}
var b bytes.Buffer
b.Write([]byte(`{"`))
for i, key := range keys {
if i != 0 {
b.Write([]byte(`,"`))
}
b.WriteString(key)
b.Write([]byte(`":`))
j, err := json.Marshal(values[i])
if err != nil {
return nil, err
}
b.Write(j)
}
b.Write([]byte(`}`))
return b.Bytes(), nil
}
func (d *Data) MarshalJSON() ([]byte, error) {
// Here you can add a list of keys and values.
// Currently it is only `url` mapped to d.Url
return marshalObject(
[]string{
`url`,
},
[]interface{}{
d.Url,
},
)
}
func main() {
i := []byte(`{"name":"http://example.com"}`)
fmt.Printf("Json Input: %+s\n", i)
var d *Data
err := json.Unmarshal(i, &d)
if err != nil {
panic(err)
}
fmt.Printf("Data: %#v\n", d)
o, err := json.Marshal(d)
if err != nil {
panic(err)
}
fmt.Printf("Json Output: %+s\n", o)
}
<强>结果:强>
Json Input: {"name":"http://example.com"}
Data: &main.Data{Url:"http://example.com"}
Json Output: {"url":"http://example.com"}
<强>游乐场:强>
答案 1 :(得分:0)
如果您将JSON对象解组为map[string]interface{}
变量,您将获得对象中的所有内容,而不仅仅是几个字段。进行必要的修改应该是相当直接的,如下所示:
func nameToUrl(data []byte) ([]byte, error) {
var obj map[string]interface{}
if err := json.Unmarshal(data, &obj); err != nil {
return nil, err
}
if name, ok := obj["name"]; ok {
delete(obj, "name")
obj["url"] = name
}
return json.Marshal(obj)
}
您可以在此处进行试验:http://play.golang.org/p/0jz_HAGg3E