YAML 解析解组失败

时间:2021-03-07 04:42:53

标签: go yaml

我已经阅读了很多帖子,但经过数小时的研究和尝试后仍然无法修复它,这是我的问题。

我有这个 YAML 文件:

---
filename: "Filename.txt"
steps:
  -
    mutationRaw:
      name: "Random things..."
      pattern: "12 34 56 78 9a bc de f0"
      mask: "xxxxxxxx"
      offset: 0
      replace: "f0 de bc 9a 78 56 34 12"
  -
    mutationRaw:
      name: "Some other random things..."
      pattern: "00 00 12 34 56 78 9a bc de f0"
      mask: "xxxxxxxxxx"
      offset: 2
      replace: "11 11 f0 de bc 9a 78 56 34 12"

这是我的 Go 代码:

package main

import (
    "fmt"
    "io/ioutil"
    "gopkg.in/yaml.v3"
)

type patcherT struct {
    Filename string `yaml:"filename"`
    Steps    struct {
        MutationsRaw []struct {
            Name      string `yaml:"name"`
        } `yaml:"mutationRaw,omitempty"`
    } `yaml:"steps"`
}

func main() {
    data, err := ioutil.ReadFile("struct.yaml")
    if err != nil {
        panic(err)
    }

    var patcher patcherT
    err = yaml.Unmarshal(data, &patcher)
    if err != nil {
        panic(err)
    }

    fmt.Println("Patcher for ", patcher.Filename)
    fmt.Println("Steps :")
    for i := 0; i < len(patcher.Steps.MutationsRaw); i++ {
        fmt.Println("\t- ", patcher.Steps.MutationsRaw[i].Name)
    }
}

还有这个错误:

<块引用>

第 4 行:无法将 !!seq 解组到 struct { MutationsRaw []struct { Name string "yaml:"name"" } "yaml:"mutationRaw,omitempty"" }

请注意,可以使用mutationFile、deletionRaw、deletionFile 和其他一些文件来代替mutationRaw。我可以这样做:

type patcherT struct {
    Filename string `yaml:"filename"`
    Steps    []struct {
        MutationsRaw struct {
            Name      string `yaml:"name"`
        } `yaml:"mutationRaw,omitempty"`
    } `yaml:"steps"`
}

但是,如果我保持相同的 YAML 结构,我会丢失太多信息。我真的希望能够通过 patcherTpatcher.Steps.MutationRaw[i]、...解析我的 patcher.Steps.MutationFile[i] 结构 第一个结构使此解析成为可能,但不起作用,而第二个结构使此解析更难并需要更改 YAML,但有效。

简而言之,我如何解析这样的 YAML 结构以允许我不是在 Steps 上迭代,而是在 MutationsRaw(或 MutationsFile,...)上进行迭代?

1 个答案:

答案 0 :(得分:0)

您可以在 UnmarshalYAML 方法中使用 custom 解组逻辑实现 yaml.Unmarshaler 接口。

例如:

type patcherT struct {
    Filename string `yaml:"filename"`
    Steps   Steps `yaml:"steps"`
}

type Steps struct {
    MutationsRaw []struct {
        Name string `yaml:"name"`
    } `yaml:"mutationRaw,omitempty"`
}

func (s *Steps) UnmarshalYAML(unmarshal func(interface{}) error) error {
    var tmpSteps []struct {
        TmpMutationsRaw struct {
            Name string `yaml:"name"`
        } `yaml:"mutationRaw,omitempty"`
    }
    err := unmarshal(&tmpSteps)
    if err != nil {
        return err
    }
    *s = Steps{MutationsRaw: make([]struct {
        Name string `yaml:"name"`
    }, len(tmpSteps))}
    for i, val := range tmpSteps {
        s.MutationsRaw[i] = struct {
            Name string `yaml:"name"`
        }(struct{ Name string }{Name: val.TmpMutationsRaw.Name})
    }
    return nil
}

PLAYGROUND

相关问题