【问题标题】:YAML parsing unmarshal failsYAML 解析解组失败
【发布时间】:2021-06-05 08:34:30
【问题描述】:

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

我有这个 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"" }

请注意,除了mutationRaw,还可以使用mutationFile、deletionRaw、deletionFile 等。我可以这样做:

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

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

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

【问题讨论】:

    标签: go yaml


    【解决方案1】:

    您可以在UnmarshalYAML 方法中使用自定义解组逻辑实现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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-22
      • 2019-07-22
      • 2014-04-05
      • 2011-03-28
      相关资源
      最近更新 更多