当前位置: 首页 > 知识库问答 >
问题:

如何在保留注释的情况下解析golang中的general yaml?

陶富
2023-03-14
package main

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

type Document interface{} // change this to []yaml.Node and it will work with comments // change it to yaml.Node and it will not work

var data string = ` # Employee records
-  martin:
    name: Martin D'vloper
    job: Developer
    skills:
      - python
      - perl
      - pascal
-  tabitha:
    name: Tabitha Bitumen
    job: Developer
    skills:
      - lisp
      - fortran
      - erlang
`

func toSlice(slice interface{}) []interface{} {
    s := reflect.ValueOf(slice)
    if s.Kind() != reflect.Slice {
        panic("InterfaceSlice() given a non-slice type")
    }

    ret := make([]interface{}, s.Len())

    for i:=0; i<s.Len(); i++ {
        ret[i] = s.Index(i).Interface()
    }

    return ret
}

func main() {
    var d Document
    err := yaml.Unmarshal([]byte(data), &d)
    if err != nil {
        panic(err)
    }

    slice := toSlice(d)
    fmt.Println(reflect.ValueOf(slice[0]).Kind())

    fmt.Println(reflect.TypeOf(d))
    fmt.Println(reflect.ValueOf(d).Kind())
    output, err := yaml.Marshal(&d)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(output))

}

共有1个答案

柯立果
2023-03-14

另一方面,如果我使用(在本例中)[]yaml.node结构,它确实在内部将所有节点表示为yaml.node或[]yaml.node。

那是不准确的。go-yaml允许您将结构的任何子树保留为yaml.node以便以后处理。在此节点中,所有内容都表示为yaml.node,而作为集合(序列或映射)的节点恰好将其子节点存储为[]yaml.node。但没有节点直接表示为[]yaml.node

当您反序列化为[]YAML.node时,您将顶级节点反序列化为本机结构(片),而不构造子节点(将YAML节点加载到本机结构中的过程在规范中称为构造)。

type Document yaml.Node
var d yaml.Node

注释也将保留(toslice显然不再起作用):

- # Employee records
  martin:
      name: Martin D'vloper
      job: Developer
      skills:
        - python
        - perl
        - pascal
- tabitha:
      name: Tabitha Bitumen
      job: Developer
      skills:
        - lisp
        - fortran
        - erlang

现在我们可以看到,注释的位置不同。这是因为go-yaml仅存储在yaml.node中,该代码表示“There has been a comment before This list item”的列表项。有关注释的确切位置的信息已丢失。您应该感谢您有关于注释的任何信息,因为大多数YAML实现很早就放弃了它们,因为规范规定注释不能传达内容信息。

您可能想读我想加载一个YAML文件,可能编辑数据,然后再次转储。如何保留格式?其中详细介绍了在加载YAML文件过程中信息丢失的原因、时间和方式。TL;DR:在保留所有格式的同时加载一个YAML文件并将其转储回去是不可能的(基本上不进行自己的解析),如果这是您的目标,那么YAML对您来说不是一个合适的工具。

 类似资料:
  • 问题内容: 我想在处理XML时尽可能忠实地保留注释。 我设法保留了注释,但是内容已被XML转义。 但是,像这样的注释: 最终为: 我也尝试过,但似乎没有任何作用。实际上,我认为问题出在步骤之后的某个地方。 顺便说一句,这个问题与此类似。 问题答案: 经过Python 2.7和3.5的测试,以下代码应该可以正常工作。 然后,在主代码中使用 作为解析器,而不是当前的解析器。 顺便说一下,使用开箱即用的

  • 问题内容: 当前使用Python 2.4.3,并且不允许升级 我想更改一个或多个标记中给定属性的值,以及更新文件中的XML注释。 我设法创建了一个以XML文件作为参数的Python脚本,并且为每个指定的标签更改了一个属性,如下所示 一切都很好,属性“ initialState”已更新,除了我的原始XML也包含许多XML注释的事实,但它们早已消失了,这是不好的。 怀疑只能解析XML结构,但我认为XM

  • 问题内容: 我正在使用@cacheable注解缓存函数的结果。我有3个不同的缓存,每个缓存的关键是当前登录的用户的用户ID,该用户ID与方法中的参数连接在一起。在某个事件中,我想逐出所有具有以该特定用户ID开头的键的缓存条目。例如 : 我希望缓存逐出注释为: 但是当我尝试实现这一点时,它给了我一个错误: 什么是实现此目的的正确方法? 问题答案: 每个操作所有Spring Cache批注(即,等)都

  • 这是我的建筑。格雷德尔: 我试图找出问题所在,使用以下代码来分析问题: 结果是:

  • 问题内容: 我正在处理备份脚本,并希望压缩文件目录: 这可以压缩它,但是当我解压生成的文件时,它包括完整的文件结构:这些文件位于中。 有没有一种方法可以排除父目录,从而使生成的tar只知道最后一个目录()? 问题答案:

  • 我试图了解DI在我们的代码库(Kotlin)中是如何使用的。我们正在使用googleguice进行依赖注入。 下面是一个示例类: 在模块类中: DepB类别: 据我所知,对于用< code>@Inject注释的变量,Google Guice会使用模块类来解决这些依赖关系。所以< code>DepA对象的注入方式是有意义的。 但是呢?我们如何能够在不指定任何位置的情况下注入DepB?