在 Go 中将数据结构解组回 YAML 时是否可以保留锚点、注释和引用?

lea*_*arn 3 yaml go

在 Go 中将数据结构解组回 YAML 时是否可以保留锚点等?

下面的这些相关问题与使用 Python 的相同概念有关,这似乎可以使用 ruyamel.yaml 包,并且根据文档https://yaml.readthedocs.io/en/latest/example.html似乎可以保留评论、锚点和参考文献。这被称为“往返”。

使用https://github.com/go-yaml/yaml中的 README.md 中的示例代码,我能够将 yaml 文件读入数据结构。然后,我使用压缩文档的锚点和参考文献导出了另一个示例。但是,当转储回 YAML 时,锚定等就会丢失。在 Golang 中可以做同样的事情吗?

fly*_*lyx 7

go-yaml 有一个相当小的接口,因为它是 Go 包的典型接口。Marshaler由于您可以(通过/Unmarshaler接口)访问的最低可能结构是yaml.Node,因此在不更改 go-yaml 本身的情况下不可能用它实现往返(就像 ruamel 是 PyYAML 的分支一样)。

\n\n

为了正确的往返,您需要:

\n\n
    \n
  • 保留注释和空白。这需要在词法分析器级别发生,很少有 YAML 实现在外部覆盖这一级别(libyaml 是我知道的唯一一个这样做的,但你不能将词法分析器标记反馈回其中,所以它基本上对此毫无用处目的)
  • \n
  • 保留标量表示。这是最难做到的,因为带引号的标量允许您转义任何 unicode 字符,并且如果您只有结果字符串,则无法知道原始表示形式。我认为甚至鲁梅尔也无法重现标量表示。标量表示还包括折叠标量中的换行符、chomping 和缩进指示器,这些都没有在 go-yaml 中公开。
  • \n
  • 保留锚点和别名。go-yaml 实际上允许您访问它,Node.Anchor但是您需要弄清楚哪个是第一个具有锚点的节点,哪些是其他最初的别名。这很困难,因为\xe2\x80\xa6
  • \n
  • 保留关键顺序。YAML 定义映射中键的顺序不得传达内容信息。通常,映射被加载到哈希图中,该哈希图会丢失此信息(就像 Go 的情况一样map)。但是,Node确实提供了子项目的原始顺序,因此这在 go-yaml 中是可行的。
  • \n
  • 保留文档页眉和页脚。YAML 允许在文档之前使用指令(%YAML%TAG),并且还允许文档以多行结尾...(以及中间的注释)。go-yaml 不提供此信息。
  • \n
\n\n

由于严格解释的话,往返违反 YAML 规范(因为它不允许表示细节对处理产生任何影响),因此它通常不是 YAML 实现的一部分,并且 afaik ruamel 是唯一尝试这样做的实现。

\n\n

所以答案是:当然可以在 Go 中实现,但是你需要自己实现,可能通过 fork go-yaml 来实现。由于解析 YAML 本身非常复杂(参见此处,没有一种实现能够完全正确),因此覆盖所有边缘情况的正确 YAML 往返实现编写起来将非常复杂,我强烈建议不要这样做。

\n