流式yaml解析,但解码两次

问题描述 投票:0回答:1

我用它来解析一个文件中包含多个文档的 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() 我会解析下一个文档......

如何解决?

go yaml
1个回答
1
投票

首先将文档解组为

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)
    }
}

游乐场

© www.soinside.com 2019 - 2024. All rights reserved.