如何通过对节点的完全访问权限来解组Golang Yaml v3

时间:2019-05-31 20:14:53

标签: go yaml

我正在尝试学习使用yaml v3解编组,并在复杂的嵌入式结构中完全访问Node。

The announcement帖子介绍了如何使用yaml.Node,但没有给出严肃的示例。而且docs也没有显示正在使用Node。

例如,我使用公告文章的扩展名

package main

import(
    "fmt"
    "gopkg.in/yaml.v3"
    "os"
)

func main() {

    type Person struct {
        Name    string
        Address yaml.Node
    }

    data := `
name: John Doe
address: 
    street: 123 E 3rd St
    city: Denver
    state: CO
    zip: 81526
`

    var person Person
    err := yaml.Unmarshal([]byte(data), &person)
    if (err != nil) {
        fmt.Printf("Failed to unmarshall: %v", err)
        os.Exit(1)
    }
    fmt.Printf("Marshalled person=%v", person)

}

但是,如果我尝试使用地址项,则会发现它们每个都作为节点内的Content数组列出;那里没有实际有用的信息。

Modify existing yaml file and add new data and comments也处理相同的区域,但在解组到结构后没有显示导航结构。

一旦解组后如何导航“地址”节点?

2 个答案:

答案 0 :(得分:0)

您必须声明完整的结构,而不是使用 yaml.Node

package main

import (
    "fmt"
    "gopkg.in/yaml.v3"
    "os"
)

func main() {
    type Address struct {
        Street string
        City   string
        State  string
        Zip    string
    }
    type Person struct {
        Name    string
        Address Address
    }



data := `
    name: John Doe
    address: 
        street: 123 E 3rd St
        city: Denver
        state: CO
        zip: 81526
    `

    var person Person
    err := yaml.Unmarshal([]byte(data), &person)
    if (err != nil) {
        fmt.Printf("Failed to unmarshall: %v", err)
        os.Exit(1)
    }
    fmt.Printf("Marshalled person=%v", person)
}

yaml.Node似乎是中间表示。 必须对其进行解码以获取值。

package main

import (
    "fmt"
    "gopkg.in/yaml.v3"
    "os"
)

func main() {
    type Address struct {
        Street string
        City   string
        State  string
        Zip    string
    }
type Person struct {
    Name    string
    Address yaml.Node
}

data := `
name: John Doe
address: 
    street: 123 E 3rd St
    city: Denver
    state: CO
    zip: 81526
`

var person Person
err := yaml.Unmarshal([]byte(data), &person)
if (err != nil) {
    fmt.Printf("Failed to unmarshall: %v", err)
    os.Exit(1)
}
address := &Address{}
_ = person.Address.Decode(address)
fmt.Printf("Marshalled person=%v\n %v", person, *address)

}

答案 1 :(得分:0)

所以Node结构具有三个字段,分别是:

// HeadComment holds any comments in the lines preceding the node and
// not separated by an empty line.
HeadComment string

// LineComment holds any comments at the end of the line where the node is in.
LineComment string

// FootComment holds any comments following the node and before empty lines.
FootComment string

此^来自文档here。在上面的示例中稍作扩充:

package main

import (
    "fmt"
    "os"

    "gopkg.in/yaml.v3"
)

func main() {
    type Person struct {
        Name    yaml.Node
        Address yaml.Node
    }

    data := `
name: John Doe
#comment here
address: 
    street: 123 E 3rd St
    city: Denver
    state: CO
    zip: 81526
`

    var person Person
    err := yaml.Unmarshal([]byte(data), &person)
    if err != nil {
        fmt.Printf("Failed to unmarshall: %v", err)
        os.Exit(1)
    }
    address := &yaml.Node{}

    decErr := person.Address.Decode(address)
    if decErr != nil {
        fmt.Printf("Failed to decode: %v", decErr)
        os.Exit(1)
    }
    fmt.Printf("%v", address.HeadComment)
}

在我们的情况下

#comment here
address: 
    street: 123 E 3rd St
    city: Denver
    state: CO
    zip: 81526

可以称为Node,并且可以从Node结构中的字段访问其注释。但是,尽管我能够访问文档中指出的其他字段,但仍然无法在Node上方获得注释。