将yaml转换为不带struct的json

将yaml转换为不带struct的json,第1张

将yaml转换为不带struct的json

前言:
我优化并改进了以下解决方案,并将其作为库发布在这里:

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配置的深度大于一,则此尝试将失败,因为此

body
映射将包含其他类型为的映射
map[interface{}]interface{}

问题在于深度是未知的,并且可能有除地图以外的其他值,因此使用

map[string]map[string]interface{}
效果不好。

一种可行的方法是让

yaml
解组为type的值
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: %sn", 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: %sn", 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: 111111Output: {"Services":[{"Orders":[    {"ID":"$save ID1","SupplierOrderCode":"$SupplierOrderCode"},    {"ID":"$save ID2","SupplierOrderCode":111111}]}]}

需要注意的一件事:通过Go映射从yaml转换为JSON,您将失去项目的顺序,因为Go映射中的元素(键-值对)未排序。这可能是问题,也可能不是问题。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5462970.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-12
下一篇2022-12-11

发表评论

登录后才能评论

评论列表(0条)

    保存