无法从通过YAML获取的映射中提取键/值对

问题描述 投票:0回答:2

我使用 goldmark-meta 包来读取 YAML 文件。 我感兴趣的内容是这样的 在 YAML 中:

burger:
- a: ay
- b: bee
- c: see

我想访问键和值 返回的界面,我被卡住了。 迭代返回给了我一个 键/值对的列表,但我没有 当我不知道时知道如何获取任何信息 提前知道按键名称。 该程序打印出以下内容:

func (c *config) burger() string {
    // c.pageFm is type map[string]interface{}
    b, ok := c.pageFm["burger"].([]interface{})
    if !ok {
    // No burger entry  in yaml
        return ""
    }
  debug("Burger list has %v items:\n%v", len(b), b)  
  debug("Type: %v", reflect.TypeOf(b))
  for i := 0; i < len(b); i++ {
    debug("%v", b[i])
  }
 return ""
}
Burger list has 3 items:
[map[a:ay] map[b:bee] map[c:see]]
Type: []interface {}
map[a:ay]
map[b:bee]
map[c:see]

如何获取key和value字符串?

go
2个回答
1
投票

在 YAML 数据中,您有一个键 (

burger
),其值是映射列表(每个映射都有一个键)。我们可以像这样迭代
burger
中的项目:

b, ok := c.pageFm["burger"].([]interface{})
if !ok {
  return ""
}

for _, item := range burger {
  ...
}

对于每个

item
,我们可以迭代可用的键和值:

for _, item := range burger {
  for k, v := range item.(map[interface{}]interface{}) {
    ...
  }
}

我们可以使用

interface{}
将键和值从
string
转换为
fmt.Sprintf
:

for _, item := range burger {
  for k, v := range item.(map[interface{}]interface{}) {
    k_str := fmt.Sprintf("%v", k)
    v_str := fmt.Sprintf("%v", v)

    fmt.Printf("key %s value %s\n", k_str, v_str)
  }
}

goldmark-meta

 中的 示例代码开始,我整理了这个示例:

package main

import (
    "bytes"
    "fmt"

    "github.com/yuin/goldmark"
    meta "github.com/yuin/goldmark-meta"
    "github.com/yuin/goldmark/parser"
)

func main() {
    markdown := goldmark.New(
        goldmark.WithExtensions(
            meta.Meta,
        ),
    )
    source := `---
burger:
- a: ay
- b: bee
- c: see
---

# Hello goldmark-meta
`

    var buf bytes.Buffer
    context := parser.NewContext()
    if err := markdown.Convert([]byte(source), &buf, parser.WithContext(context)); err != nil {
        panic(err)
    }
    metaData := meta.Get(context)
    burger := metaData["burger"].([]interface{})
    for _, item := range burger {
        for k, v := range item.(map[interface{}]interface{}) {
            k_str := fmt.Sprintf("%v", k)
            v_str := fmt.Sprintf("%v", v)
            fmt.Printf("key %s value %s\n", k_str, v_str)
        }
    }
}

哪个输出:

key a value ay
key b value bee
key c value see

0
投票

我会坚持(如果可以的话)自动化你的代码,并使用定义结构使读/写 yaml 相同。对结构进行编码/解码。 当然,这需要非动态 yaml。 这是布局:

burger:
- a: ay
- b: bee
- c: see

type Burgers struct {
   burgers map[string]Burger
}
type Burger struct {
   name string
}
var c Burgers
c.burgers["a"] = Burger{name ="ay",}
c.burgers["b"] = Burger{name ="bee",}
c.burgers["b"] = Burger{name ="cee",}
file, err := os.OpenFile("some.yaml", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0600)
enc := yaml.NewEncoder(file)
err = enc.Encode(c)

然后读回 yaml:

 yamlFile, err := os.Open(filePath)
 dec := yaml.NewDecoder(yamlFile)
 err = dec.Decode(c)

您将得到这个 yaml(将其视为键/名称元组):

 burgers:
    a:
       name: ay
    b:
       name: bee
    c:
       name: cee

格式略有不同,但只有一个结构体和 4 行代码,基本上:

 NewDecoder
 Encode

 NewDecoder
 Decode
 
© www.soinside.com 2019 - 2024. All rights reserved.