为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用 Viper 从嵌套的 YAML 结构中获取值?

如何使用 Viper 从嵌套的 YAML 结构中获取值?

Go
哈士奇WWW 2023-04-17 15:07:05
如何编写下面的代码以从我的嵌套 yaml 结构中获取字符串?这是我的 yaml:element:  - one:      url: http://test      nested: 123  - two:      url: http://test      nested: 123weather:  - test:      zipcode: 12345  - ca:      zipcode: 90210这是示例代码viper.SetConfigName("main_config")  viper.AddConfigPath(".")  err := viper.ReadInConfig()  if err != nil {    panic(err)  }testvar := viper.GetString("element.one.url")我的问题:当我打印这个时,我得到一个空白字符串。根据文档,这就是获得嵌套元素的方式。我怀疑它不起作用,因为元素是列表。我需要做一个结构吗?我不确定如何制作,特别是如果它需要嵌套。
查看完整描述

3 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

您可以解组嵌套的配置文件。


主程序


package main


import (

    "fmt"

    "github.com/spf13/viper"

)


type NestedURL struct {

    URL string `mapstructure:"url"`

    Nested int `mapstructure:"nested"`

}


type ZipCode struct {

    Zipcode string `mapstructure:"zipcode"`

}


type Config struct {

    Element [] map[string]NestedURL `mapstructure:"element"`

    Weather [] map[string]ZipCode `mapstructure:"weather"`

}


func main() {

    viper.SetConfigName("config")

    viper.AddConfigPath(".")

    if err := viper.ReadInConfig();  err != nil {

        return

    }

    var config Config

    if err := viper.Unmarshal(&config); err != nil {

        fmt.Println(err)

        return

    }

    fmt.Println(config)

}

配置文件


element:

  - one:

      url: http://test

      nested: 123

  - two:

      url: http://test

      nested: 123

weather:

  - test:

      zipcode: 12345

  - ca:

      zipcode: 90210


查看完整回答
反对 回复 2023-04-17
?
临摹微笑

TA贡献1982条经验 获得超2个赞

viper 库中有不同的 Get 方法可用,并且您的 YML 结构是类型[]map[string]string,因此要解析您的 YML 配置文件,您必须使用viper.Get方法。所以你必须像这样解析你的文件..

注意:您也可以使用 struct 来取消编组数据。

package main


import (

    "fmt"


    "github.com/spf13/viper"

)


func main() {

    viper.SetConfigName("config")

    viper.AddConfigPath(".")

    err := viper.ReadInConfig()

    if err != nil {

        panic(err)

    }

    testvar := viper.Get("element")

    fmt.Println(testvar)

    elementsMap := testvar.([]interface{})

    for k, vmap := range elementsMap {

        fmt.Print("Key: ", k) 

        fmt.Println(" Value: ", vmap)

        eachElementsMap := vmap.(map[interface{}]interface{})


        for k, vEachValMap := range eachElementsMap {

            fmt.Printf("%v: %v \n", k, vEachValMap)

            vEachValDataMap := vEachValMap.(map[interface{}]interface{})


            for k, v := range vEachValDataMap {

                fmt.Printf("%v: %v \n", k, v)

            }

        }

    }

}


// Output:

/*

Key: 0 Value:  map[one:map[url:http://test nested:123]]

one: map[url:http://test nested:123]

url: http://test

nested: 123

Key: 1 Value:  map[two:map[url:http://test nested:123]]

two: map[url:http://test nested:123]

url: http://test

nested: 123

*/


查看完整回答
反对 回复 2023-04-17
?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

您可以使用Unmarshal或UnmarshalKey解析全部或部分数据并填充结构。它与解组 json 非常相似。


在你的情况下,代码将是这样的:


package main


import (

    "fmt"

    "github.com/spf13/viper"

)


// here we define schema of data, just like what we might do when we parse json

type Element struct {

    Url    string `mapstructure:"url"`

    Nested int    `mapstructure:"nested"`

}


func main() {

    viper.SetConfigName("config")

    viper.AddConfigPath(".")

    err := viper.ReadInConfig()

    if err != nil {

        panic(err)

    }

    

    // data in `element` key is a map of string to Element. We define a variable to store data into it.

    elementParsed := make(map[string]*Element)

    // read the key `element` in the yaml file, and parse it's data and put it in `elementParsed` variable

    err = viper.UnmarshalKey("element", &elementParsed)

    if err != nil {

        panic(err)

    }


    fmt.Println(elementParsed["one"].Url) // will print: http://test 

    fmt.Println(elementParsed["one"].Nested) // will print: 123

}


查看完整回答
反对 回复 2023-04-17
  • 3 回答
  • 0 关注
  • 171 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信