解组YAML文件-如何以前导零作为字符串读取YAML参数? [英] Unmarshal YAML file - How to read YAML parameters with leading zeros as a string?

查看:119
本文介绍了解组YAML文件-如何以前导零作为字符串读取YAML参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在不进行任何转换的情况下以前导零作为字符串读取YAML属性?

How to read YAML properties with leading zeros as string without any conversion?

YAML示例文件:

provisioning:
  devices: 
    000000001515:
        properties: 
          example: 30s
        options:
          dummy: true

Golang代码-最小的可重现示例:

Golang Code - Minimal reproducible example:

package main

import (
    "fmt"
    "github.com/ghodss/yaml"
)

//DeviceSpec device
type DeviceSpec struct {
    Properties map[string]string `yaml:"properties,omitempty"`
    Options    map[string]string `yaml:"options,omitempty"`
}

//Spec provisi
type Spec struct {
    Provisioning struct {
        Devices map[string]DeviceSpec `yaml:"devices,omitempty"`
    }
}

var input = []byte(`
provisioning:
  devices: 
    000000001515:
        properties: 
          example: 30s
        options:
          dummy: true
`)

func main() {
   config := Spec{}
   if err := yaml.Unmarshal(input, &config); err != nil {
        panic(err)
   }

   for uuid, _ := range config.Provisioning.Devices {
      fmt.Println(uuid)
   }
}

输出

845

预期产量

000000001515

解决方案

该问题与我正在使用" github.com/ghodss/yaml"的YAML软件包有关.v1.0.0 .用"gopkg.in/yaml.v3" 包替换它可以解决此问题,并且效果很好-请在下面的注释部分-谢谢大家.

The issue was related to the YAML package I was using "github.com/ghodss/yaml" v1.0.0. Replacing it with the "gopkg.in/yaml.v3" package fixed the issue and it works just fine - see the comment section bellow - thank you all.

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


注意:这个问题与此类似,但是这个问题使用的是Python:推荐答案

现在我们发现了错误,让我们对发生的事情进行事后调查:

Now that we found the error, let's have a post mortem about what happened:

您使用的库 github.com/ghodss/yaml 表示

此库首先使用go-yaml将YAML转换为JSON,然后使用json.Marshal和json.Unmarshal在结构之间进行转换.

this library first converts YAML to JSON using go-yaml and then uses json.Marshal and json.Unmarshal to convert to or from the struct.

链接的博客文章关于为什么这样做是一个好主意的消失并没有什么特别的帮助.无论如何,让我们看看其中的代码实际上是:

It doesn't particularly help that the linked blog post about why this would be a good idea vanished. Anyway, let's see what the code there actually does:

var yamlObj interface{}
err := yamlUnmarshal(y, &yamlObj)

因此它将您的YAML输入输入并将其加载到接口中.当您实际提供目标类型时,这是一个的主意.此处发生的是,go-yaml可以自由选择目标类型,如果是,它显然会读取前导零作为八进制数字的数字.这与YAML 1.1 的 !! int标记的过时定义一致:

So it takes your YAML input and loads it into an interface. This as a bad idea when you actually supply the target type. What happens here is that go-yaml is free to choose the target types, and if it is, it apparently reads in numbers with leading zeros as octal numbers. This is in line with the outdated definition of the !!int tag for YAML 1.1:

[-+]?0[0-7_]+ # (base 8)

但是, YAML 1.2 早已取代了这一点:

However, that has long been superseded by YAML 1.2:

 0o [0-7]+   tag:yaml.org,2002:int (Base 8)

go-yaml似乎实现了YAML 1.1规则.这似乎是一个错误的决定,并且可能是偶然地完成的,因此可能需要出具问题报告.

go-yaml seems to implement the YAML 1.1 rule. This seems a bad decision and may have been done accidentally, possibly warranting an issue report.

因此,无论如何,当加载YAML时,该值将被解释为八进制值.github.com/ghodss/yaml继续将值转换为JSON,然后再次将其解组,但我们已经丢失了.

So anyway, when the YAML gets loaded, the value gets interpreted as octal value. github.com/ghodss/yaml proceeds to mangle the value into JSON and then unmarshal it again, but we've already lost.

要点是,我认为github.com/ghodss/yaml有害,建议不要使用它.

The takeaway is that I would consider github.com/ghodss/yaml harmful and advise not to use it.

这篇关于解组YAML文件-如何以前导零作为字符串读取YAML参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆