我正在寻找一种解组JSON主体的方法,而无需为所有字段指定目标。然后是一个能够重新制造"隐含领域的身体未受影响。
这样的事情会很好,但不会像预期的那样奏效:(https://play.golang.org/p/fnVOKrmiFj)
<div id='cssmenu'>
<ul>
<li><a href='#'>Home</a>
<ul>
<li><a href='#'>Product 1</a></li>
<li><a href='#'>Product 2</a></li>
<li><a href='#'>Product 3</a></li>
</ul>
</li>
<li><a class='active' href='#'>Products</a>
</li>
<li><a href='#'>About</a>
</li>
<li><a href='#'>Contact</a></li>
</ul>
</div>
提供输出
package main
import (
"encoding/json"
"fmt"
)
type Transaction struct {
Field1 string `json:"field1"`
X map[string]interface{} `json:"-"`
}
func main() {
body := []byte(`{"field1": "value1", "field2": "value2"}`)
fmt.Printf("%+v\n", string(body))
var unmarshalledTransaction Transaction
json.Unmarshal(body, &unmarshalledTransaction)
fmt.Printf("%+v\n", unmarshalledTransaction)
remarshalledTransaction, _ := json.Marshal(&unmarshalledTransaction)
fmt.Printf("%+v\n", string(remarshalledTransaction))
}
我的预期结果是{"field1": "value1", "field2": "value2"}
{Field1:value1 X:map[]}
{"field1":"value1"}
包含&#34;剩余的&#34; unmarshalledTransaction
字段中的字段。然后在再次编组时恢复它们。
可以这样做吗?
答案 0 :(得分:1)
您需要实现MarshalJSON
和UnmarshalJSON
接口,并编写自己的逻辑以将字段重新映射到适当的位置:
func (t *Transaction) MarshalJSON() ([]byte, error) {
data := t.X
data["field1"] = t.Field1
return json.Marshal(data)
}
func (t *Transaction) UnmarshalJSON(data []byte) error {
m := make(map[string]interface{})
json.Unmarshal(data, &m)
t.Field1 = m["field1"].(string)
delete(m, "field1")
t.X = m
return nil
}
答案 1 :(得分:0)
如果你想要一个通用的解决方案(可以在不事先知道字段的情况下使用任何结构),你可以实现一个将主体解组为结构并返回“剩余”字段的函数。 p>
为此,您还需要实现一个将任何给定结构转换为地图的函数(用于以通用方式操作地图而不是预先知道的结构)。
像这样:
func structToMap(object interface{}) (map[string]interface{}, error) {
tempJson, err := json.Marshal(object)
if err != nil {
return nil, err
}
var theMap map[string]interface{}
err = json.Unmarshal(tempJson, &theMap)
if err != nil {
return nil, err
}
return theMap, nil
}
然后:
func unmarshalWithLeftovers(jsonBody []byte, target interface{}) (map[string]interface{}, error) {
err := json.Unmarshal(jsonBody, target)
if err != nil {
return nil, err
}
structMap, err := structToMap(target)
if err != nil {
return nil, err
}
var leftOvers map[string]interface{}
err = json.Unmarshal(jsonBody, &leftOvers)
if err != nil {
return nil, err
}
for k, _ := range structMap {
delete(leftOvers, k)
}
return leftOvers, nil
}
然后,您可以以类似的方式组合结构和剩余地图,以重新编组所有内容。
请在此处查看您在问题中使用的具有相同类型和json字符串的工作示例: