我用它来解析一个文件中包含多个文档的 yaml:
package main
import (
"errors"
"fmt"
"io"
"os"
"gopkg.in/yaml.v3"
)
type Spec struct {
Name string `yaml:"name"`
}
func main() {
f := io.Reader(os.Stdin)
d := yaml.NewDecoder(f)
for {
var spec Spec
err := d.Decode(&spec)
if errors.Is(err, io.EOF) {
break
}
if err != nil {
panic(err)
}
fmt.Printf("name is '%s'\n", spec.Name)
}
}
现在我想解码当前对象两次。
根据当前文档中的名称,我想解析它:
type Special struct {
Integer string `yaml:"integer"`
}
但是如果我使用 d.Decode() 我会解析下一个文档......
如何解决?
首先将文档解组为
Node
,然后使用 Node
的 Decode
方法对结果节点进行多次解码(请参阅 文档)。
修改后的示例如下所示:
package main
import (
"errors"
"fmt"
"io"
"strings"
"gopkg.in/yaml.v3"
)
const data = `
---
name: "foo"
integer: 42
---
name: "bar"
integer: 12
`
type Spec struct {
Name string `yaml:"name"`
}
type Special struct {
Integer string `yaml:"integer"`
}
func main() {
dec := yaml.NewDecoder(strings.NewReader(data))
for {
var node yaml.Node
err := dec.Decode(&node)
if errors.Is(err, io.EOF) {
break
}
if err != nil {
panic(err)
}
spec := new(Spec)
err = node.Decode(&spec)
if err != nil {
panic(err)
}
// check it was parsed
if spec == nil {
fmt.Println("# spec is nil")
continue
}
fmt.Printf("name is '%s'\n", spec.Name)
var si Special
err = node.Decode(&si)
if err != nil {
panic(err)
}
fmt.Println("integer is: ", si.Integer)
}
}
游乐场。