Yaml: parsing data sequence into list

Created on 14 Dec 2016  ·  3Comments  ·  Source: go-yaml/yaml

The data is

-
  ip: 192.168.1.1
  role: master
-
  ip: 192.168.1.2
  role: node
-
  ip: 192.168.1.3
  role: node

The struct is

type NODE struct {
    node []struct {
        ipaddr string
        role   string
    } `yaml:",flow"`
}

The parsing code is

    n := NODE{}

    err := yaml.Unmarshal([]byte(data), &n)
    if err != nil {
        log.Fatalf("error: %v", err)
    }
    fmt.Printf("--- t:\n%v\n\n", n)

then it failed with following infos:

2016/12/14 17:13:39 error: yaml: unmarshal errors:
  line 2: cannot unmarshal !!seq into main.NODE

Most helpful comment

After struggling with this for a couple hours, I figured it out 5 minutes after pinging this thread (apologies for that!) The comment in https://github.com/go-yaml/yaml/issues/101#issuecomment-178792007 was a huge help.

In my case, I was trying to parse Ansible's requirements.yaml file which looks like this:

---
- src: franklinkim.php5-newrelic
- src: geerlingguy.composer
- src: geerlingguy.java
- src: geerlingguy.nginx
- src: geerlingguy.nodejs
- src: geerlingguy.php
- src: geerlingguy.php-versions
- src: geerlingguy.rabbitmq
- src: geerlingguy.solr
- src: newrelic.newrelic-infra

- name: mycustomrole
  src: [email protected]:foo/bar.git
  scm: git
  version: master

- src: https://github.com/nickhammond/ansible-logrotate
  name: nickhammond.logrotate

I had a struct like this, which was correct:

type AnsibleSource struct {
    Source  string  `yaml:"src"`
    Name    *string `yaml:"name,omitempty"`
    Type    *string `yaml:"scm,omitempty"`
    Version *string `yaml:"version,omitempty"`
}

But to properly unmarshall the top-level sequence (and solve the cannot unmarshal !!seq error) I had to unmarshall it via var out []AnsibleSource like so:

    source, err := ioutil.ReadFile(ansibleRequirements.Path)
    if err != nil {
        return
    }

    var out []AnsibleSource

    err = yaml.Unmarshal(source, &out)
    if err != nil {
        return
    }

    fmt.Println(requirements)

Hope this helps someone else!

All 3 comments

@vanloswang I'm getting this same error. How did you solve this?

@alexforever86 Did you ever find a solution?

After struggling with this for a couple hours, I figured it out 5 minutes after pinging this thread (apologies for that!) The comment in https://github.com/go-yaml/yaml/issues/101#issuecomment-178792007 was a huge help.

In my case, I was trying to parse Ansible's requirements.yaml file which looks like this:

---
- src: franklinkim.php5-newrelic
- src: geerlingguy.composer
- src: geerlingguy.java
- src: geerlingguy.nginx
- src: geerlingguy.nodejs
- src: geerlingguy.php
- src: geerlingguy.php-versions
- src: geerlingguy.rabbitmq
- src: geerlingguy.solr
- src: newrelic.newrelic-infra

- name: mycustomrole
  src: [email protected]:foo/bar.git
  scm: git
  version: master

- src: https://github.com/nickhammond/ansible-logrotate
  name: nickhammond.logrotate

I had a struct like this, which was correct:

type AnsibleSource struct {
    Source  string  `yaml:"src"`
    Name    *string `yaml:"name,omitempty"`
    Type    *string `yaml:"scm,omitempty"`
    Version *string `yaml:"version,omitempty"`
}

But to properly unmarshall the top-level sequence (and solve the cannot unmarshal !!seq error) I had to unmarshall it via var out []AnsibleSource like so:

    source, err := ioutil.ReadFile(ansibleRequirements.Path)
    if err != nil {
        return
    }

    var out []AnsibleSource

    err = yaml.Unmarshal(source, &out)
    if err != nil {
        return
    }

    fmt.Println(requirements)

Hope this helps someone else!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

michaelsauter picture michaelsauter  ·  28Comments

rnix picture rnix  ·  3Comments

tonglil picture tonglil  ·  8Comments

rogpeppe picture rogpeppe  ·  7Comments

mro picture mro  ·  13Comments