Forepick
Forepick

Reputation: 937

Golang yaml.v2 marshals an array as a sequence

Given the following YAML:

array.test: ["val1", "val2", "val3"]

I Unmarshal it using gopkg.in/yaml.v2 into a map[string]interface{}. Then I get a single key whose value is an array of 3 values.

When I then Marshal it again to YAML, the resulting YAML looks like this:

array.test:
- val1
- val2
- val3

The array was actually marshaled as a sequence instead of an array.

This is the entire GoLang code:

func main(){
    data := `array.test: ["val1", "val2", "val3"]`
    conf := make(map[string]interface{})
    yaml.Unmarshal([]byte(data), conf)

    data2, _ := yaml.Marshal(conf)
    fmt.Printf("%s\n", string(data2))
}

How can I overcome this issue?

Upvotes: 0

Views: 19118

Answers (3)

Shudipta Sharma
Shudipta Sharma

Reputation: 5872

This one helped me in the same case as you.

package main

import (
        "fmt"
        "log"

        "gopkg.in/yaml.v2"
)

var data = `
a: Easy!
b:
c: 2
d.test: ["d1", "d2"]
`

// Note: struct fields must be public in order for unmarshal to
// correctly populate the data.
type T struct {
    A string
    B struct {
            RenamedC int   `yaml:"c"`
            DTest        []string `yaml:"d.test,flow"`
    }
}

func main() {
    // if we use struct containing yaml encoding for yaml formated string 
    t := T{}

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

    d, err := yaml.Marshal(&t)
    if err != nil {
            log.Fatalf("error: %v", err)
    }
    fmt.Printf("--- t after marshal:\n%s\n\n", string(d))
}

Ref: https://github.com/go-yaml/yaml

Upvotes: 5

iHelos
iHelos

Reputation: 131

Flow tag allows you to choose the representation of an array in yaml

package main

import (
    "fmt"
    "gopkg.in/yaml.v2"
)

type Conf struct {
    Test []string `yaml:"array.test,flow"`
}

func main(){
    data := `array.test: ["val1", "val2", "val3"]`
    var conf Conf
    yaml.Unmarshal([]byte(data), &conf)

    data2, _ := yaml.Marshal(conf)
    fmt.Printf("%s\n", string(data2))
}

Upvotes: 2

Jonathan Hall
Jonathan Hall

Reputation: 79614

Use flow in struct field tag format, to indicate you desire this behavior. But, of course, this requires unmarshaling to a struct, not to a map.

Upvotes: 1

Related Questions