如何从我的 YAML 文件中访问 ‘map[string]interface {}’ 数据?

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

How to access 'map[string]interface {}' data from my yaml file

问题

我有一个yaml文件,我正在尝试读取并循环遍历以提取其中的一些数据。

我的yaml示例:

  1. ---
  2. THE/NAME/DOESNT/MATTER:
  3. TEST_NAME: THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML
  4. RUN_PATH: example/testfiles/release
  5. SOMETHING_ELSE: [1,2,3]
  6. ANOTHER/PATH/LIKE/STRING:
  7. TEST_NAME: USED/FOR/THE/HTML
  8. RUN_PATH: example/testfiles/foo

我的代码:

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "io/ioutil"
  6. "gopkg.in/yaml.v3"
  7. )
  8. func main() {
  9. reportYAML := os.Args[1]
  10. yfile, err := ioutil.ReadFile(reportYAML)
  11. if err != nil {
  12. fmt.Printf("ERROR: Unable to open yaml file : %s\n", err)
  13. }
  14. data := make(map[interface{}]interface{})
  15. error := yaml.Unmarshal([]byte(yfile), &data)
  16. if error != nil {
  17. fmt.Printf("ERROR: Unable to read yaml file : %s\n", err)
  18. }
  19. for _, value := range data {
  20. fmt.Printf("%T\n", value)
  21. }
  22. }

yaml文件将以类似的模式重复出现,我正在尝试提取TEST_NAME和RUN_PATH。使用%T打印出来的结果是map[string]interface {},使用%s打印出来的结果是map[RUN_PATH:example/testfiles/release SOMETHING_ELSE:[%!s(int=1) %!s(int=2) %!s(int=3)] TEST_NAME:THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML]

我尝试过value["TEST_NAME"]value.(string)["TEST_NAME"]value["TEST_NAME"].(string)和其他几种变体,但都会出现错误。

我知道这是一个简单的问题,但我对GO的经验很少,无法从以前的类似stackoverflow帖子中解决它。

附加上下文:每个yaml顶级键将包含多个键值对,但我只对TEST_NAME和RUN_PATH感兴趣。

英文:

I have a yaml file i am trying to read in and loop over to extract some of the data.

example of my yaml

  1. ---
  2. THE/NAME/DOESNT/MATTER:
  3. TEST_NAME: THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML
  4. RUN_PATH: example/testfiles/release
  5. SOMETHING_ELSE: [1,2,3]
  6. ANOTHER/PATH/LIKE/STRING:
  7. TEST_NAME: USED/FOR/THE/HTML
  8. RUN_PATH: example/testfiles/foo

my code

  1. package main
  2. import (
  3. "fmt"
  4. "os"
  5. "io/ioutil"
  6. "gopkg.in/yaml.v3"
  7. )
  8. func main() {
  9. reportYAML := os.Args[1]
  10. // userDictionary := os.Args[2]
  11. yfile, err := ioutil.ReadFile(reportYAML)
  12. if err != nil {
  13. fmt.Printf("ERROR: Unable to open yaml file : %s\n", err)
  14. }
  15. data := make(map[interface{}]interface{})
  16. error := yaml.Unmarshal([]byte(yfile), &data)
  17. if error != nil {
  18. fmt.Printf("ERROR: Unable to read yaml file : %s\n", err)
  19. }
  20. for _, value := range data {
  21. fmt.Printf("%T\n", value)
  22. }
  23. }

the yaml will repeat with a similar pattern and i am trying to extract both TEST_NAME and RUN_PATH. Printf with %T gives me map[string]interface {} and %s map[RUN_PATH:example/testfiles/release SOMETHING_ELSE:[%!s(int=1) %!s(int=2) %!s(int=3)] TEST_NAME:THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML]

I've been trying value["TESTNAME"], value.(string)["TESTNAME"], value["TESTNAME"].(string) and a few other variations but they all give me errors.

I know this is a simple problem but i have very little experience with GO and can't work it out from previous, similar stackoverflow posts

additional context: each yaml top-level-key will contain multiple key:value pairs but i am only interested in the TEST_NAME and RUN_PATH

答案1

得分: 1

如果你只关心几个特定的键,只需创建一个数据结构来公开这些值:

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "gopkg.in/yaml.v3"
  7. )
  8. type (
  9. Entry struct {
  10. TestName string `yaml:"TEST_NAME"`
  11. RunPath string `yaml:"RUN_PATH"`
  12. }
  13. )
  14. func main() {
  15. reportYAML := os.Args[1]
  16. // userDictionary := os.Args[2]
  17. yfile, err := ioutil.ReadFile(reportYAML)
  18. if err != nil {
  19. fmt.Printf("ERROR: 无法打开 yaml 文件:%s\n", err)
  20. }
  21. data := make(map[string]Entry)
  22. error := yaml.Unmarshal([]byte(yfile), &data)
  23. if error != nil {
  24. fmt.Printf("ERROR: 无法读取 yaml 文件:%s\n", err)
  25. }
  26. for _, value := range data {
  27. fmt.Printf("test_name: %s\n", value.TestName)
  28. fmt.Printf("run_path: %s\n", value.RunPath)
  29. }
  30. }

运行上述代码对你的示例数据进行处理会产生以下结果:

  1. test_name: THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML
  2. run_path: example/testfiles/release
  3. test_name: USED/FOR/THE/HTML
  4. run_path: example/testfiles/foo
英文:

If you only care about a few specific keys, just create a data structure to expose those values:

  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "gopkg.in/yaml.v3"
  7. )
  8. type (
  9. Entry struct {
  10. TestName string `yaml:"TEST_NAME"`
  11. RunPath string `yaml:"RUN_PATH"`
  12. }
  13. )
  14. func main() {
  15. reportYAML := os.Args[1]
  16. // userDictionary := os.Args[2]
  17. yfile, err := ioutil.ReadFile(reportYAML)
  18. if err != nil {
  19. fmt.Printf("ERROR: Unable to open yaml file : %s\n", err)
  20. }
  21. data := make(map[string]Entry)
  22. error := yaml.Unmarshal([]byte(yfile), &data)
  23. if error != nil {
  24. fmt.Printf("ERROR: Unable to read yaml file : %s\n", err)
  25. }
  26. for _, value := range data {
  27. fmt.Printf("test_name: %s\n", value.TestName)
  28. fmt.Printf("run_path: %s\n", value.RunPath)
  29. }
  30. }

Running the above code against your example data produces:

  1. test_name: THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML
  2. run_path: example/testfiles/release
  3. test_name: USED/FOR/THE/HTML
  4. run_path: example/testfiles/foo

huangapple
  • 本文由 发表于 2022年11月10日 20:57:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/74389367.html
匿名

发表评论

匿名网友

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

确定