如何扩展go yaml以支持自定义标记

如何扩展go yaml以支持自定义标记,go,yaml,Go,Yaml,我已经花了一些时间阅读的代码和文档,但我没有找到任何方法来做到这一点,除了分叉项目 我想扩展YAML解组器,以便它可以接受自定义YAML标记(!在本例中为include),这将允许我添加对包含文件的支持。这很容易通过其他YAML库实现,如中 有没有办法使用库(或另一个yaml库)的公共界面来实现这一点?是的,这是可能的(因为v3)。您可以将整个YAML文件加载到YAML.Node中,然后遍历该结构。诀窍在于yaml.Node是一种中间表示,只有在定义解组器时才能访问它。 例如: 主程序包 进口(

我已经花了一些时间阅读的代码和文档,但我没有找到任何方法来做到这一点,除了分叉项目

我想扩展YAML解组器,以便它可以接受自定义YAML标记(
!在本例中为include
),这将允许我添加对包含文件的支持。这很容易通过其他YAML库实现,如中

有没有办法使用库(或另一个yaml库)的公共界面来实现这一点?

是的,这是可能的(因为
v3
)。您可以将整个YAML文件加载到
YAML.Node
中,然后遍历该结构。诀窍在于
yaml.Node
是一种中间表示,只有在定义解组器时才能访问它。 例如:

主程序包
进口(
“错误”
“fmt”
“io/ioutil”
“gopkg.in/yaml.v3”
)
//用于加载包含的文件
类型片段结构{
content*yaml.Node
}
func(f*Fragment)解组字符串(值*yaml.Node)错误{
变量错误
//该过程包含在片段中
f、 内容,err=resolveIncludes(值)
返回错误
}
类型IncludeProcessor结构{
目标接口{}
}
func(i*IncludeProcessor)解组字符串(值*yaml.Node)错误{
已解析,错误:=resolveIncludes(值)
如果错误!=零{
返回错误
}
返回已解析。解码(i.目标)
}
func resolveIncludes(节点*yaml.node)(*yaml.node,错误){
如果node.Tag==“!include”{
if node.Kind!=yaml.ScalarNode{
返回nil,errors.New(“!包含在非标量节点上”)
}
文件,err:=ioutil.ReadFile(node.Value)
如果错误!=零{
返回零,错误
}
变异f片段
err=yaml.Unmarshal(文件(&f)
返回f.content,err
}
如果node.Kind==yaml.SequenceNode | | node.Kind==yaml.MappingNode{
变量错误
对于i:=范围节点.Content{
node.Content[i],err=resolveIncludes(node.Content[i])
如果错误!=零{
返回零,错误
}
}
}
返回节点,无
}
类型MyStructure struct{
//此结构保存处理后要加载的值
//包括,例如。
Num int
}
func main(){
var s MyStructure
yaml.Unmarshal([]字节(“!include foo.yaml”),&IncludeProcessor{&s})
fmt.Printf(“数量:%v”,s.Num)
}

代码打印Num:42当文件foo.yaml包含Num:42

内容时,我忘了注意到有人修改了go-yaml以提供准确的此功能,但它是在分叉和未使用的repo上:go-yaml不支持此功能,这就是为什么在公共API中找不到它的原因。你得用叉子叉。