【问题标题】:How can I create a JSON structure dynamically from Go?如何从 Go 动态创建 JSON 结构?
【发布时间】:2010-12-16 18:26:20
【问题描述】:

如序列化 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));
}

【问题讨论】:

  • 您查看过golang.org/pkg/json 的文档吗?不导出带下划线的标识符。
  • @devyn - 高亮语法基于固定的编码标准,可能是 C# 和 Java 的结合。
  • 还记得类是如何命名的吗?大写字母在前。

标签: json go


【解决方案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);

【讨论】:

  • Scott,首先这是 JSON 包的一部分,所以如果不做改动就无法编译。其次,它似乎正在获取字符串并针对它们测试解析器。我认为这根本不是原始海报所要问的。 devyn 似乎想从数据结构中创建 JSON。
  • 我添加了一个如何使用 sn-p 的示例。如有必要,可以从 [] 字符串轻松构建杂货数组。
  • 非常有趣,但我真正想做的是完全动态地创建一个 JSON 字符串,例如对于 JSON-RPC 服务器?
  • 我可能最终会构建自己的 JSON 序列化库。
【解决方案2】:

这是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。在库源代码文件generic.go 中有一个很好的例子来说明如何使用_Null 来实现embedding

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 2019-07-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多