【问题标题】:Unmarshal struct into string including comments将结构解组为包含注释的字符串
【发布时间】:2020-07-27 20:15:17
【问题描述】:

我想部分读取 yaml,即解码 Type/Description 键,但将定义结构的 Sample 键保留为纯字符串。目的是为解码定义测试数据集。

例子:

type: default
description: test data
sample:
  some: # want
    complex: # comments
    - struct # included

我希望sample 的子键以纯字符串形式返回。

我尝试过使用带解组器接口的别名类型 (gopkg.in/yaml.v2):

type plain string // implements UnmarshalYAML

但以:

结尾
panic: yaml: unmarshal errors:
  line 4: cannot unmarshal !!map into []uint8

我找不到使用UnmarshalYAML 和自定义字符串类型或强制转换为字符串的简单方法?

【问题讨论】:

  • 请包含一个示例输入 (yaml) 并指明您想要的结果。还发布您迄今为止尝试过的内容以及您正在使用的 yaml 库。
  • 抱歉问题不清楚,已按要求扩展。使用 yaml 解析器而不是模式匹配会很好

标签: go yaml


【解决方案1】:

您应该知道,通过阅读 cmets,您违反了 YAML 规范,该规范明确规定 cmets 不得传达内容信息。

无论如何,go-yaml v3 为中间子结构提供了 yaml.Node 类型:

package main

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

type file struct {
  Type string
  Description string
  Sample yaml.Node
}

var input []byte = []byte(`
type: default
description: test data
sample:
  some: # want
    complex: # comments
    - struct # included
`)

func main() {
  var f file
  var err error
  if err = yaml.Unmarshal(input, &f); err != nil {
    panic(err)
  }
  var out []byte
  if out, err = yaml.Marshal(&f.Sample); err != nil {
    panic(err)
  }
  fmt.Println(string(out))
}

打印出来

some: # want
    complex: # comments
      - struct # included

它通过将结构存储到yaml.Node 中来工作,该yaml.Node 确实存储了cmets。然后它将节点呈现为独立的 YAML 文档。

您可以通过遍历节点结构来访问 cmets。

字符串与原始字符串不同,因为 YAML 在加载时总是会丢失一些信息。如果您需要以精确间距获取值,则确实需要将子树编码为文字块标量,就像您在答案中显示的那样。

【讨论】:

    【解决方案2】:

    我通过在 yaml 中将 sample 定义为字符串来修改我的方法:

    type: default
    description: test data
    sample: |
      some: # want
        complex: # comments
        - struct # included
    

    这更像是一种解决方法,但很简单......

    【讨论】:

      猜你喜欢
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-21
      • 2020-04-20
      相关资源
      最近更新 更多