我正在尝试动态解析yaml文件(因此没有结构)。
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"log"
)
func main() {
var out = `
a: First!
f: Second
b:
c:
f: Third
`
m := make(map[interface{}]interface{})
err := yaml.Unmarshal([]byte(out), &m)
if err != nil {
log.Fatal(err)
}
fmt.Println(m["b"].(map[interface{}]interface{})["c"].(map[interface{}]interface{})["f"])
}
每次我必须访问一个子项时,我都被迫将有问题的map变量转换为(map [interface {}] interface {})。这对我来说有点麻烦,因为我必须遍历地图。
在Go中解析YAML文件有没有更简单的方法?
答案 0 :(得分:1)
另一种方法是将yaml数据结构展平为键值映射,其中键和值是字符串。然后,如果您需要实际类型(5为int),您可以自己进行转换。例如:
"a" = "First!"
"f" = "Second"
"b.c.f" = "Third"
"b.c.g.size" = "2"
"b.c.g.0 = "zero"
"b.c.g.1 = "one"
Go:
func main() {
any := map[string]interface{}{}
err := yaml.Unmarshal([]byte(out), &any)
if err != nil {
log.Fatal(err)
}
flatmap := map[string]string{}
for k, v := range any {
flatten(k, v, flatmap)
}
for k, v := range flatmap {
fmt.Println(k, "=", v)
}
}
func flatten(prefix string, value interface{}, flatmap map[string]string) {
submap, ok := value.(map[interface{}]interface{})
if ok {
for k, v := range submap {
flatten(prefix+"."+k.(string), v, flatmap)
}
return
}
stringlist, ok := value.([]interface{})
if ok {
flatten(fmt.Sprintf("%s.size", prefix), len(stringlist), flatmap)
for i, v := range stringlist {
flatten(fmt.Sprintf("%s.%d", prefix, i), v, flatmap)
}
return
}
flatmap[prefix] = fmt.Sprintf("%v", value)
}