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

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

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

问题

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

我的yaml示例:

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

我的代码:

package main
import (
	"fmt"
	"os"
	"io/ioutil"

	"gopkg.in/yaml.v3"
)

func main() {
	reportYAML := os.Args[1]

	yfile, err := ioutil.ReadFile(reportYAML)
	if err != nil {
		fmt.Printf("ERROR: Unable to open yaml file : %s\n", err)
	}
	data := make(map[interface{}]interface{})
    error := yaml.Unmarshal([]byte(yfile), &data)
    if error != nil {
        fmt.Printf("ERROR: Unable to read yaml file : %s\n", err)
    }
    for _, value := range data {
        fmt.Printf("%T\n", value)
    }
}

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

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

my code

package main
import (
	"fmt"
	"os"
	"io/ioutil"

	"gopkg.in/yaml.v3"
)

func main() {
	reportYAML := os.Args[1]
	// userDictionary := os.Args[2]

	yfile, err := ioutil.ReadFile(reportYAML)
	if err != nil {
		fmt.Printf("ERROR: Unable to open yaml file : %s\n", err)
	}
	data := make(map[interface{}]interface{})
    error := yaml.Unmarshal([]byte(yfile), &data)
    if error != nil {
        fmt.Printf("ERROR: Unable to read yaml file : %s\n", err)
    }
    for _, value := range data {
        fmt.Printf("%T\n", value)
    }
   	
}

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

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

package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"gopkg.in/yaml.v3"
)

type (
	Entry struct {
		TestName string `yaml:"TEST_NAME"`
		RunPath  string `yaml:"RUN_PATH"`
	}
)

func main() {
	reportYAML := os.Args[1]
	// userDictionary := os.Args[2]

	yfile, err := ioutil.ReadFile(reportYAML)
	if err != nil {
		fmt.Printf("ERROR: 无法打开 yaml 文件:%s\n", err)
	}
	data := make(map[string]Entry)
	error := yaml.Unmarshal([]byte(yfile), &data)
	if error != nil {
		fmt.Printf("ERROR: 无法读取 yaml 文件:%s\n", err)
	}
	for _, value := range data {
		fmt.Printf("test_name: %s\n", value.TestName)
		fmt.Printf("run_path: %s\n", value.RunPath)
	}
}

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

test_name: THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML
run_path: example/testfiles/release
test_name: USED/FOR/THE/HTML
run_path: example/testfiles/foo
英文:

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

package main

import (
	"fmt"
	"io/ioutil"
	"os"

	"gopkg.in/yaml.v3"
)

type (
	Entry struct {
		TestName string `yaml:"TEST_NAME"`
		RunPath  string `yaml:"RUN_PATH"`
	}
)

func main() {
	reportYAML := os.Args[1]
	// userDictionary := os.Args[2]

	yfile, err := ioutil.ReadFile(reportYAML)
	if err != nil {
		fmt.Printf("ERROR: Unable to open yaml file : %s\n", err)
	}
	data := make(map[string]Entry)
	error := yaml.Unmarshal([]byte(yfile), &data)
	if error != nil {
		fmt.Printf("ERROR: Unable to read yaml file : %s\n", err)
	}
	for _, value := range data {
		fmt.Printf("test_name: %s\n", value.TestName)
		fmt.Printf("run_path: %s\n", value.RunPath)
	}
}

Running the above code against your example data produces:

test_name: THIS/IS/WHAT/IS/DISPLAYS/ON/THE/HTML
run_path: example/testfiles/release
test_name: USED/FOR/THE/HTML
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:

确定