doufan6544 2019-05-31 20:14
浏览 190

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

I'm trying to learn to use YAML v3 unmarshaling with full access to the Node in a complex embedded struct.

The announcement post explains how to use yaml.Node, but doesn't give a serious example. And the documentation also doesn't show working with the Node. The primary purpose seems to be the excellent preservation of comments in YAML files.

For example, working with an extension of the announcement article, I have

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 # street is like an avenue
    city: Denver  # A city might be a town as well
    state: CO  # A state might be a province or administrative unit
    zip: 81526 # zip might be "postal_code"
`

    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)

}

But if I try to use the address items, I find them each listed as an array of Content inside the node; there's no actual useful information there. The comments are in there, but it's not clear what they're associated with.

Modify existing yaml file and add new data and comments also deals with the same territory, but doesn't show navigating the structure after unmarshalling into the struct.

How can I navigate the "Address" node once unmarshalled, and preserve the comments on marshalling again?

  • 写回答

2条回答 默认 最新

  • doutang6819 2019-06-01 19:10
    关注

    You have to declare the complete struct instead of using 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 seems like an intermediate representation. It has to be decoded to get the values.

    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
     %v", person, *address)
    
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 unity第一人称射击小游戏,有demo,在原脚本的基础上进行修改以达到要求
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)