如何从Go动态创建JSON结构?

时间:2009-11-15 10:19:30

标签: json go

如同序列化JSON。

我当前的代码不起作用,我认为它必须与_Map,_String等不公开的事实有关。

// 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));
}

3 个答案:

答案 0 :(得分:1)

看看$ GOROOT / src / pkg / json / generic_test.go中的TestJsonMap函数,它似乎做了类似于你想要的东西。相关代码是

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);

您希望将值“world”推送到名称“hello”和[“Eggs”,“Bread”,“Milk”]到“Groceries”。尝试

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);

答案 1 :(得分:1)

以下是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;
}

以下是一些测试代码:

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));
}

通过定义Json包的接口,将JsonToString方法放在类型MyTest上。显然,这并没有做任何有趣的事情,但您可以为您的特定数据结构定义各种类似的东西,以便拥有一个“JSON-izer”,它可以从您的结构中创建您喜欢的任何JSON。有一个很好的示例,说明如何使用库源代码文件_Null中名为generic.go的内容embedding

答案 2 :(得分:1)

This看起来很有希望。

//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}}}