我正在尝试解析此Yaml,并且我想获取values
条目(test1或test2)的run
而不成功,这是我的工作示例。
我有点迷失于map :(, 这是给我可以改变的yaml ...
知道如何获得这些值
package main
import (
"fmt"
"log"
"gopkg.in/yaml.v2"
)
var runContent = []byte(`
version: "3.2"
run-parameters:
before:
run-parameters:
run: test1
after:
run-parameters:
run: test2
`)
type FTD struct {
Version string `yaml:"version,omitempty"`
BuildParams *RunParams `yaml:"run-parameters,omitempty"`
}
type RunParams struct {
BeforeExec map[string]interface{} `yaml:"before,omitempty"`
AfterExec map[string]interface{} `yaml:"after,omitempty"`
}
func main() {
runners := &FTD{}
// parse mta yaml
err := yaml.Unmarshal(runContent, runners)
if err != nil {
log.Fatalf("Error : %v", err)
}
for k, v := range runners.BuildParams.BeforeExec {
fmt.Println(k, v.(interface{}))
}
}
这是工作示例 https://play.golang.org/p/qTqUJy3md0c
我也尝试过
这有效
run := runners.BuildParams.BeforeExec["run-parameters"].(map[interface{}]interface{})["run"]
fmt.Println("run: ", run)
我尝试过的是可行的,但是如果run
值为空或根本没有任何条目怎么办,这将导致转储,我该如何克服呢?
答案 0 :(得分:1)
我尝试过的是可以正常工作的,但是如果运行值为空或根本没有条目怎么办,这将导致转储,我该如何克服呢?
您可以
runParams, ok := runners.BuildParams.BeforeExec["run-parameters"]
if !ok {
// handle lack of "run-parameters" in BeforeExec
}
runParamsMap, ok := runParams.(map[interface{}]interface{})
if !ok {
// handle "run-parameters" not being a map
}
run, ok := runParamsMap["run"]
if !ok {
// handle lack of "run" inside "run-parameters"
}
runStr, ok := run.(string)
if !ok {
// handle "run" not being a string
}
fmt.Println("run: ", runStr)
这很冗长,因此您可以使用类似https://github.com/jmoiron/jsonq的名称,您可以在其中指定嵌套在多个地图级别中的所需值的“路径”。尽管名称中带有“ json”,该库仍可使用map [string] interface {}而不是json文件。但是请注意,用于yaml解组的库将以map[interface{}]interface{}
而不是map[string]interface{}
的形式出现,并且您必须使用其他库才能使其与jsonq一起使用。
run, err := jsonq.NewQuery(runners.BuildParams.BeforeExec).String("run-parameters", "run")
if err != nil {
// handle all possible errors in one place
}
fmt.Println("run: ", run)