Go 如何在完全访问节点的情况下解组YAML v3

Go 如何在完全访问节点的情况下解组YAML v3,go,yaml,Go,Yaml,我试图学习使用YAML v3解组,在复杂的嵌入式结构中完全访问节点 这篇文章解释了如何使用yaml.Node,但没有给出一个严肃的例子。并且也不显示如何使用节点。主要目的似乎是出色地保存YAML文件中的注释 例如,使用公告文章的扩展,我有 主程序包 进口( “fmt” “gopkg.in/yaml.v3” “操作系统” ) func main(){ 类型Person结构{ 名称字符串 地址:yaml.Node } 数据:=` 姓名:无名氏 地址: 街道:123 E第三大街就像一条大街 城市:丹佛

我试图学习使用YAML v3解组,在复杂的嵌入式结构中完全访问节点

这篇文章解释了如何使用yaml.Node,但没有给出一个严肃的例子。并且也不显示如何使用节点。主要目的似乎是出色地保存YAML文件中的注释

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

主程序包
进口(
“fmt”
“gopkg.in/yaml.v3”
“操作系统”
)
func main(){
类型Person结构{
名称字符串
地址:yaml.Node
}
数据:=`
姓名:无名氏
地址:
街道:123 E第三大街就像一条大街
城市:丹佛——一个城市也可能是一个城镇
州:州可以是省或行政单位
邮政编码:81526#邮政编码可能是“邮政编码”
`
变量人
错误:=yaml.Unmarshal([]字节(数据),&个人)
如果(错误!=nil){
fmt.Printf(“未能解组:%v”,错误)
操作系统退出(1)
}
fmt.Printf(“封送人员=%v”,人员)
}
但是如果我尝试使用地址项,我会发现它们在节点内都列为内容数组;那里没有实际有用的信息。评论在那里,但不清楚它们与什么有关

也处理相同的区域,但不显示在解组到结构后导航结构


如何在取消编组后导航“地址”节点,并再次保留编组注释?

您必须声明完整的结构,而不是使用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)

}

因此,节点结构有三个字段:

// 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
本文件摘自文档。对上面的示例稍加扩充:

主程序包
进口(
“fmt”
“操作系统”
“gopkg.in/yaml.v3”
)
func main(){
类型Person结构{
名称yaml.Node
地址:yaml.Node
}
数据:=`
姓名:无名氏
#评论这里
地址:
街道:东三街123号
城市:丹佛
国家:公司
邮政编码:81526
`
变量人
错误:=yaml.Unmarshal([]字节(数据),&个人)
如果错误!=零{
fmt.Printf(“未能解组:%v”,错误)
操作系统退出(1)
}
地址:=&yaml.Node{}
decErr:=person.Address.Decode(地址)
如果decErr!=nil{
fmt.Printf(“解码失败:%v”,decErr)
操作系统退出(1)
}
fmt.Printf(“%v”,地址:HeadComment)
}
就我们而言

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

可以称为节点,其注释可以从节点结构中的字段访问。但我仍然无法获得节点上方的注释,尽管我可以访问文档中指出的其他字段。

感谢您指出Decode()。不过,我仍然不理解节点的正确使用,因为最大的好处是能够保留注释并将它们保留在正确的位置。如果不能将节点的内容绑定在一起,我不知道如何成功地做到这一点。我更新了问题,将重点放在获取评论上。