- yaml库
- 多文档
import "gopkg.in/yaml.v2"
该库可以很方便的操作yaml文件,这里先展示一下常用的解析方法:
假设有如下a.yml文件:
a: 10 b: - 1 - 2 - 3
这个yaml很简单,里面包含了一个int型的变量a,和一个int型的数组变量b。那么与之对应的结构体也很好构造:
type YmlObj struct {
A int
B []int
}
使用yaml包来解析也很简单,这里我就用go的单元测试来写这个方法了:
func TestGetYamlByUnmarshal(t *testing.T) {
y := YmlObj{}
content, err := ioutil.ReadFile("a.yml")
if err != nil{
t.Error(err)
}
if err = yaml.Unmarshal(content, &y);err != nil{
t.Error(err)
}
fmt.Println(y)
}
多文档
这里说的多文档,并不是指多个yaml文件,这很简单和上面没什么区别。
在yaml中,严格的讲,每个yaml文件都应该以---开头,注意,这是三个短横线。因此如果在一个yaml文件中包含多个---,那么就相当于多个yml文档,例如b.yml:
--- a: 10 b: - 1 - 2 - 3 --- a: 20 b: - 4 - 5
这种情况在k8s中非常常见,我之前自己处理的时候想法也很简单,将文件读取为字符串,然后用strings.split(str, "---")来把这个文件分割为多个文档,然后在逐一解析。
可是这样是有问题的,前几天我遇到一份yml文档中包含多个连续的短横线,那结果也可以预见:yml文档被分割成了多个不完整的部分,解析自然也会失败。
实际上yaml这个包对于这种情况是有官方的解决方案的:decode
下面上代码:
func TestGetYaml(t *testing.T) {
file, err := os.Open("b.yaml")
if err != nil{
t.Error(err)
}
dec := yaml.NewDecoder(file)
y := YmlObj{}
err := dec.Decode(&y)
for err == nil{
fmt.Println(y)
err = dec.Decode(&y)
}
if !errors.Is(err, io.EOF){
t.Error(err)
}
fmt.Println("Parse yaml complete!")
}
可以看出来,yaml.NewDecoder返回的decoder在调用Decode方法的时候,每次都会从该文件中取出一个yaml文档进行解析,该文件中的所有文档都读取完成后,就会返回一个io.EOF的error,如果判断是该error,就代表以及解析完毕。



