在没有结构的情况下将 yaml 转换为 json
Posted
技术标签:
【中文标题】在没有结构的情况下将 yaml 转换为 json【英文标题】:Convert yaml to json without struct 【发布时间】:2017-04-05 20:22:10 【问题描述】:Services:
- Orders:
- ID: $save ID1
SupplierOrderCode: $SupplierOrderCode
- ID: $save ID2
SupplierOrderCode: 111111
我想把这个yaml字符串转换成json,因为源数据是动态的,所以我不能把它映射到结构体:
var body interface
err := yaml.Unmarshal([]byte(s), &body)
那我想再把那个接口转成json字符串:
b, _ := json.Marshal(body)
但是发生错误:
panic: json: unsupported type: map[interface ]interface
【问题讨论】:
像这样创建正文变量:body := make(map[string]interface)
【参考方案1】:
前言:我对以下解决方案进行了优化和改进,并在此处将其作为库发布:github.com/icza/dyno
。以下convert()
函数可作为dyno.ConvertMapI2MapS()
使用。
问题在于,如果您使用最通用的interface
类型来解组,则github.com/go-yaml/yaml
包用于解组键值对的默认类型将是map[interface]interface
。
第一个想法是使用map[string]interface
:
var body map[string]interface
但如果 yaml 配置的深度大于 1,则此尝试会失败,因为此 body
映射将包含其他类型将再次为 map[interface]interface
的映射。
问题是深度未知,可能还有地图以外的其他值,所以使用map[string]map[string]interface
不好。
一种可行的方法是让yaml
解组为interface
类型的值,并递归地处理结果,并将遇到的每个map[interface]interface
转换为map[string]interface
值。地图和切片都必须处理。
下面是这个转换器函数的一个例子:
func convert(i interface) interface
switch x := i.(type)
case map[interface]interface:
m2 := map[string]interface
for k, v := range x
m2[k.(string)] = convert(v)
return m2
case []interface:
for i, v := range x
x[i] = convert(v)
return i
并使用它:
func main()
fmt.Printf("Input: %s\n", s)
var body interface
if err := yaml.Unmarshal([]byte(s), &body); err != nil
panic(err)
body = convert(body)
if b, err := json.Marshal(body); err != nil
panic(err)
else
fmt.Printf("Output: %s\n", b)
const s = `Services:
- Orders:
- ID: $save ID1
SupplierOrderCode: $SupplierOrderCode
- ID: $save ID2
SupplierOrderCode: 111111
`
输出:
Input: Services:
- Orders:
- ID: $save ID1
SupplierOrderCode: $SupplierOrderCode
- ID: $save ID2
SupplierOrderCode: 111111
Output: "Services":["Orders":[
"ID":"$save ID1","SupplierOrderCode":"$SupplierOrderCode",
"ID":"$save ID2","SupplierOrderCode":111111]]
需要注意的一点:通过 Go 映射从 yaml 切换到 JSON,您将失去项目的顺序,因为 Go 映射中的元素(键值对)没有排序。这可能是也可能不是问题。
【讨论】:
非常感谢 Icza,你真好 :D【参考方案2】:http://sigs.k8s.io/yaml 是“一个围绕 go-yaml 的包装器,旨在在编组到结构体和从结构体传出时提供更好的 YAML 处理方式”。除此之外,它还提供了yaml.YAMLToJSON
方法,可以满足您的需求。
【讨论】:
以上是关于在没有结构的情况下将 yaml 转换为 json的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有可选值的情况下将字典数组快速转换为json字符串[重复]
如何在不将 LocalDateTime 字段转换为扩展的 json 对象的情况下将 java 对象转换为简单的 json 字符串?
如何在不使用 C# 中的 T 对象的情况下将 Json 数组转换为单个 JSON 对象?