dongtuo5262
2018-08-16 13:36
浏览 201
已采纳

在Golang中解析yaml时出错

I’ve a yaml like following which I need to parse using go. When I tried to run the code with the parse I got an error. Below is the code:

var runContent= []byte(`

- runners:
   - name: function1
     type: func1
      - command: spawn child process
      - command: build
      - command: gulp

  - name: function1
    type: func2
      - command: run function 1
  - name: function3
    type: func3
      - command: ruby build

  - name: function4
    type: func4
      - command: go build 

`)

These are the types:

type Runners struct {

    runners string `yaml:"runners"`
        name string `yaml:”name”`
        Type: string  `yaml: ”type”`
        command  [] Command 
}


type Command struct {
    command string `yaml: ”command”`
}



runners := Runners{}
err = yaml.Unmarshal(runContent, &runners)
if err != nil {
    log.Fatalf("Error : %v", err)
}

When I try to parse it I got an error invalid map , what could be missing here ?

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongshan9619 2018-08-16 14:00
    已采纳

    The code you have posted contains multiple errors including the struct field Type. The yaml provided in your code is not valid. This will lead to err when unmarshalling the yaml into struct.

    On unmarshalling yaml in go, It is required that:

    The type of the decoded values should be compatible with the respective values in out. If one or more values cannot be decoded due to a type mismatches, decoding continues partially until the end of the YAML content, and a *yaml.TypeError is returned with details for all missed values.

    Along with that:

    Struct fields are only unmarshalled if they are exported (have an upper case first letter), and are unmarshalled using the field name lowercased as the default key.

    Also there is an error in defining the yaml tags, which contains space. Custom keys may be defined via the "yaml" name in the field tag: the content preceding the first comma is used as the key.

    type Runners struct {
    
        runners string `yaml:"runners"` // fields should be exportable
            name string `yaml:”name”`
            Type: string  `yaml: ”type”` // tags name should not have space in them.
            command  [] Command 
    } 
    

    To make the struct exportable convert the struct and fields into uppercase starting letter and remove space in yaml tag names:

    type Runners struct {
        Runners string `yaml:"runners"`
        Name string `yaml:"name"`
        Type string `yaml:"type"`
        Command  []Command 
    }
    
    type Command struct {
        Command string `yaml:"command"`
    }
    

    Modify the code as below to make it work.

    package main
    
    import (
        "fmt"
        "log"
    
        "gopkg.in/yaml.v2"
    )
    
    var runContent = []byte(`
    - runners:
      - name: function1
        type:
        - command: spawn child process
        - command: build
        - command: gulp
      - name: function1
        type:
        - command: run function 1
      - name: function3
        type:
        - command: ruby build
      - name: function4
        type:
        - command: go build
    `)
    
    type Runners []struct {
        Runners []struct {
            Type []struct {
                Command string `yaml:"command"`
            } `yaml:"type"`
            Name string `yaml:"name"`
        } `yaml:"runners"`
    }
    
    func main() {
    
        runners := Runners{}
        // parse mta yaml
        err := yaml.Unmarshal(runContent, &runners)
        if err != nil {
            log.Fatalf("Error : %v", err)
        }
        fmt.Println(runners)
    }
    

    Playground example

    Validate your yaml online here https://codebeautify.org/yaml-validator/cb92c85b

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题