将动态结构序列化为JSON

huangapple go评论151阅读模式
英文:

Serialize to JSON dynamic structure

问题

所有关于使用JSON的示例都描述了如何将简单类型或用户类型(如结构体)序列化为JSON。

但是我有一个不同的情况:a)我不知道我的类型/对象的字段;b)每个对象的类型都不同。

以下是我伪代码中的情况:

while `select * from item` do
  while `select fieldname, fieldvalue from fields where fields.itemid = item.id` do
    ...

对于数据库中的每个实体,我获取字段名和字段值。结果应该如下所示:

{
  "item.field1": value,
  ...
  "item.fieldN": value,
  "custom_fields": {
     "fields.field1": value,
      ...
     "fields.fieldK": value
  }
}

在Go语言中,最佳方法是什么?标准库中是否有任何有用的库或函数?

**更新:**数据的来源是数据库。结果中,我需要将JSON作为字符串进行POST请求到外部Web服务。因此,程序只需从数据库中读取数据并向REST服务发出POST请求。

英文:

All examples of working with JSON describe how to serialize to JSON simple or user types (like a struct).

But I have a different case: a) I don't know the fields of my type/object b) every object will have different types.

Here is my case in pseudocode:

while `select * from item` do
  while `select fieldname, fieldvalue from fields where fields.itemid = item.id` do
    ...

For each entity in my database I get field names and field values. In the result I need to get something like this:

{
  "item.field1": value,
  ...
  "item.fieldN": value,
  "custom_fields": {
     "fields.field1": value,
      ...
     "fields.fieldK": value
  }
}

What is the best way to do it in Go? Is there any useful libraries or functions in standard library ?

Update: The source of data is the database. In the result i need to get JSON as string to POST it to external web service. So, the program just read data from database and make POST requests to REST service.

答案1

得分: 1

你的目标类型应该是什么?由于你事先不知道字段,所以它不能是一个结构体。

对我来说,唯一合适的类型似乎是map类型的map[string]interface{}:通过它可以实现任何嵌套结构:

a := map[string]interface{}{
    "item.field1": "val1",
    "item.field2": "val2",
    "item.fieldN": "valN",
    "custom_fields": map[string]interface{}{
        "fields.field1": "cval1",
        "fields.field2": "cval2",
    },
}
b, err := json.Marshal(a)

在这里可以查看示例代码:playground sample

从数据库中填充这个结构,正如你所暗示的,可能需要一个自定义脚本(不使用json)。

注意:custom_fields也可以是其他类型,这取决于数据库中值列的类型。如果值列是字符串,请使用map[string]string

英文:

What exactly is your target type supposed to be? It can't be a struct since you do not know the fields beforehand.

The only fitting type to me seems to be a map of type map[string]interface{}: with it any nested structure can be achieved:

a := map[string]interface{}{
	"item.field1": "val1",
	"item.field2": "val2",
	"item.fieldN": "valN",
	"custom_fields": map[string]interface{}{
		"fields.field1": "cval1",
		"fields.field2": "cval2",
	},
}
b, err := json.Marshal(a)

See playground sample here.

Filling this structure from a database as you hinted at should probably be a custom script (not using json).

Note: custom_fields can also be of other types depending on what type the value column is in the database. If the value column is a string use map[string]string.

huangapple
  • 本文由 发表于 2017年8月7日 20:40:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/45547169.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定