有没有更简单的方法使用Golang JSON编码在JSON对象上添加图层?
Go中开箱即用的
JSON编码非常好,但我需要通过添加图层来使输出与特定格式匹配.我已经找到了一种方法,但希望有一种比我正在做的方式更简单的方法.
下面是我如何做的一个例子. import ( "bytes" "encoding/json" "encoding/xml" "fmt" ) type Query struct { XMLName xml.Name `xml:"http://marklogic.com/appservices/search query" json:"-"` Format int `xml:"-" json:"-"` Queries []interface{} `xml:",any" json:"queries"` } type TermQuery struct { XMLName xml.Name `xml:"http://marklogic.com/appservices/search term-query" json:"-"` Terms []string `xml:"http://marklogic.com/appservices/search text" json:"text"` Weight float64 `xml:"http://marklogic.com/appservices/search weight,omitempty" json:"weight,omitempty"` } // use fakeQuery to avoid an infinite loop type fakeQuery Query //MarshalJSON for Query struct in a special way to add wraping {"query":...} func (q Query) MarshalJSON() ([]byte,error) { return wrapJSON(`query`,fakeQuery(q)) } // use fakeTermQuery to avoid an infinite loop type fakeTermQuery TermQuery //MarshalJSON for TermQuery struct in a special way to add wraping {"term-query":...} func (q TermQuery) MarshalJSON() ([]byte,error) { return wrapJSON(`term-query`,fakeTermQuery(q)) } func wrapJSON(name string,item interface{}) ([]byte,error) { var buffer bytes.Buffer b,err := json.Marshal(item) buffer.Write([]byte(`{"`)) buffer.Write([]byte(name)) buffer.Write([]byte(`":`)) buffer.Write(b) buffer.Write([]byte(`}`)) return buffer.Bytes(),err } 我有很多已定义的结构,我需要这样做,所以我希望有一个更好的解决方案,不会让我用100行代码来添加一个围绕JSON对象的包装器.理想情况下,我希望能够在为XML编码器定义的XML元素名称处达到顶峰并使用它来包装JSON. 在我的情况下,我使用MarshalJSON函数,因为这些结构可以嵌套.如果有帮助我总是知道Query结构是根结构. 解决方法
也许我错过了一些东西,但这就是你要找的东西吗?
我开始时的想法和@Manawasp一样(使用map [string] interface {})但是我决定尝试从结构标记中获取名称,就像你问的那样……这就是我想出的结果(*注意:可能存在未处理的错误情况,这可能会使用其他解决方案很容易处理的事情过于复杂) http://play.golang.org/p/qO6tDZjtXA package main import ( "fmt" "reflect" "strings" ) import ( "encoding/json" "encoding/xml" "errors" ) type Query struct { XMLName xml.Name `xml:"http://marklogic.com/appservices/search query" json:"-"` Field1 string Field2 int64 } type TermQuery struct { XMLName xml.Name `xml:"http://marklogic.com/appservices/search term-query" json:"-"` Field3 string Field4 int64 } func getXmlName(d interface{},label string) (string,bool) { switch reflect.TypeOf(d).Kind() { case reflect.Struct: v,_ := reflect.TypeOf(d).FieldByName(label) parts := strings.Split(v.Tag.Get("xml")," ") return parts[1],true } return "",false } func wrapJson(item interface{}) ([]byte,error) { if n,ok := getXmlName(item,"XMLName"); ok { b,err := json.Marshal(map[string]interface{}{n: item}) if err != nil { return nil,err } return b,nil } return nil,errors.New("You failed") } func main() { // create a Query and encode it as {"query": {struct}} q := Query{Field1: "hello",Field2: 42} wrappedQ,err := wrapJson(q) if err != nil { fmt.Println(err) return } fmt.Println(string(wrappedQ)) // create a TermQuery and encode it as {"term-query": {struct}} tq := TermQuery{Field3: "world",Field4: 99} wrappedTQ,err := wrapJson(tq) if err != nil { fmt.Println(err) return } fmt.Println(string(wrappedTQ)) } OUTPUT {"query":{"Field1":"hello","Field2":42}} {"term-query":{"Field3":"world","Field4":99}} 编辑 http://play.golang.org/p/8MloLP3X4H package main import ( "fmt" "reflect" "strings" ) import ( //"encoding/json" "encoding/json" "encoding/xml" "errors" ) type Query struct { XMLName xml.Name `xml:"http://marklogic.com/appservices/search query" json:"-"` Field1 string Field2 int64 Queries []interface{} `xml:",any" json:"queries"` } type TermQuery struct { XMLName xml.Name `xml:"http://marklogic.com/appservices/search term-query" json:"-"` Field3 string Field4 int64 } func getXmlName(d interface{},true default: fmt.Println(reflect.TypeOf(d).Kind()) } return "",false } func wrapJson(item interface{}) (map[string]interface{},"XMLName"); ok { if k := reflect.ValueOf(item).FieldByName("Queries"); k.IsValid() { for i := 0; i < k.Len(); i++ { b,err1 := wrapJson(k.Index(i).Interface()) if err1 != nil { continue } k.Index(i).Set(reflect.ValueOf(b)) } } return map[string]interface{}{n: item},errors.New("You failed") } func asJson(i interface{}) []byte { b,err := json.Marshal(i) if err != nil { return []byte(`{"error": "too bad"}`) } return b } func main() { // create a TermQuery and encode it as {"term-query": {struct}} tq := TermQuery{Field3: "world",err := wrapJson(tq) if err != nil { fmt.Println(err) return } fmt.Println(string(asJson(wrappedTQ))) // create a Query and encode it as {"query": {struct}} q := Query{ Field1: "hello",Field2: 42,Queries: []interface{}{ TermQuery{Field3: "world",Field4: 99},TermQuery{Field3: "yay,it works!",Field4: 666},Query{ Field1: "Hi",Field2: 21,Queries: []interface{}{ TermQuery{ Field3: "omg",Field4: 1,},} wrappedQ,err := wrapJson(q) if err != nil { fmt.Println(err) return } fmt.Println(string(asJson(wrappedQ))) } PRETTY-PRINTED OUTOUT { "query": { "Field1": "hello","Field2": 42,"queries": [ { "term-query": { "Field3": "world","Field4": 99 } },{ "term-query": { "Field3": "yay,"Field4": 666 } },{ "query": { "Field1": "Hi","Field2": 21,"queries": [ { "term-query": { "Field3": "omg","Field4": 1 } } ] } } ] } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |