开发者

How can I create a JSON structure dynamically from Go?

As in, serializing JSON.

My current code doesn't work, and I think it must have something to do with the fact that _Map, _String, etc. are not public.

// vim:ft=go:ts=2

package main

import "json"
import "fmt"
import vector "container/vector"

func main() {
  groceries := vector.New(0);
  groceries.Push(&json._String{s:"Eggs"});
  groceries.Push(&json._String{s:"Bread"});
  groceries.Push(&json._String{s:"Milk"});
  var tree json.Json = &json._Map{m:map[string]json.Json{
    "hello": &json._String{s:"world"},
    "groceries": &json._Array{a:groceries}
  }};
  fmt.Printf(json.开发者_如何学编程JsonToString(tree));
}


Have a look at the TestJsonMap function in $GOROOT/src/pkg/json/generic_test.go, it seems to do something similar to what you want. The relevant code is

var jsontests = []string{
    `null`,
    `true`,
    `false`,
    `"abc"` // , etc.
}
values := make(map[string]Json);
mapstr := "{";
for i := 0; i < len(jsontests); i++ {
    val, ok, errtok := StringToJson(jsontests[i]);
    if !ok {
        t.Errorf("StringToJson(%#q) => error near %v", jsontests[i], errtok)
    }
    if i > 0 {
        mapstr += ","
    }
    values[jsontests[i]] = val;
    mapstr += Quote(jsontests[i]);
    mapstr += ":";
    mapstr += JsonToString(val);
}
mapstr += "}";

mapv, ok, errtok := StringToJson(mapstr);

You want to push the value "world" onto the name "hello" and ["Eggs","Bread","Milk"] onto "Groceries". Try

var values = make(map[string]string);
values["hello"] = `"world"`;
values["groceries"] = `["Eggs","Bread","Milk"]`;

mapstr := "{";
needcomma := false;
for key,val := range values {
    jsonval, ok, errtok := json.StringToJson(val);
    // Check errors

    // Add a comma
    if needcomma == true {
        mapstr += ",";
    } else {
        needcomma = true;
    } 

    mapstr += json.Quote(key);
    mapstr += ":";
    mapstr += json.JsonToString(jsonval);
}
mapstr += "}";
mapv, ok, errtok := json.StringToJson(mapstr);


Here is the bare bones of an implementation of the interface for Json:

package main
import {"json"; "fmt"; "os";}
type MyTest struct { MyMap map[string]string;}
func (t * MyTest) Kind()    int       { return json.MapKind  } 
func (t * MyTest) Len()     int       { return len (t.MyMap) }
func (t * MyTest) Number()  float64   { return 0 }
func (t * MyTest) Bool()    bool      { return false }
func (t * MyTest) Elem(int) json.Json { return json.Null }
func (t * MyTest) String() (s string) {
    s = "{"; 
    count := 0;
    for key, value := range t.MyMap {
        s += json.Quote(key) + ":" + json.Quote(value);
        count++;
        if (count < len (t.MyMap)) {
            s += ",";
        }
    }
    s += "}";
    return;
}
func (t * MyTest) Get(s string) json.Json {
    j, ok, errtok := json.StringToJson (t.MyMap[s]);
    if ! ok {
        fmt.Printf ("Fail at %s\n", errtok);
        os.Exit (1);
    }
    return j;
}

Here is some testing code:

func main () {
    var megaburger = new (MyTest);
    megaburger.MyMap = make(map[string]string);
    megaburger.MyMap["frog"] = "toad";
    megaburger.MyMap["captain"] = "kirk";
    megaburger.MyMap["laser"] = "phaser";
    fmt.Println (megaburger.Kind());
    fmt.Println (megaburger.Len());
    fmt.Println (json.JsonToString (megaburger));
}

This puts a JsonToString method onto the type MyTest by defining the interface for the Json package. Clearly this doesn't do anything interesting yet, but you could define various things like these for your particular data structure in order to have a "JSON-izer" which created whatever JSON you liked from your structure. There is a nice example of how to do embedding using something called _Null in the library source code file generic.go.


This looks promising.

//import "github.com/Jeffail/gabs"

jsonObj := gabs.New()
// or gabs.Consume(jsonObject) to work on an existing map[string]interface{}

jsonObj.Set(10, "outter", "inner", "value")
jsonObj.SetP(20, "outter.inner.value2")
jsonObj.Set(30, "outter", "inner2", "value3")

fmt.Println(jsonObj.String())

// Prints
// {"outter":{"inner":{"value":10,"value2":20},"inner2":{"value3":30}}}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜