douchensou6495 2019-02-21 14:52
浏览 80

golang yaml对jsonlines的支持

I've been trying to get the go yaml package to parse a file with jsonlines entries.

Below is a simple example with three options of data to be parsed.

  • Option one is a multi-doc yaml example. Both docs parse ok.

  • Option two is a two jsonline example. The first line parses ok, but the second is missed.

  • Option three is a two jsonline example, but I've put yaml doc separators in between, to force the issue. Both of these parse ok.

From reading the yaml and json specs, I believe the second option, multiple jsonlines, ought to be handled by a yaml parser.

My questions are:

  • Should a YAML parser cope with jsonlines?
  • Am I using the go yaml package correctly?

package main

import (
    "bytes"
    "fmt"
    "reflect"
    "strings"

    "gopkg.in/yaml.v2"
)

var testData = []string{
    `
---
option_one_first_yaml_doc: ok_here
---
option_one_second_yaml_doc: ok_here
`,
    `
{option_two_first_jsonl: ok_here}
{option_two_second_jsonl: missing}
`,
    `
---
{option_three_first_jsonl: ok_here}
---
{option_three_second_jsonl: ok_here}
`}

func printVal(v interface{}, depth int) {
    typ := reflect.TypeOf(v)
    if typ == nil {
        fmt.Printf(" %v
", "<null>")
    } else if typ.Kind() == reflect.Int || typ.Kind() == reflect.String {
        fmt.Printf("%s%v
", strings.Repeat(" ", depth), v)
    } else if typ.Kind() == reflect.Slice {
        fmt.Printf("
")
        printSlice(v.([]interface{}), depth+1)
    } else if typ.Kind() == reflect.Map {
        fmt.Printf("
")
        printMap(v.(map[interface{}]interface{}), depth+1)
    }
}

func printMap(m map[interface{}]interface{}, depth int) {
    for k, v := range m {
        fmt.Printf("%sKey: %s Value(s):", strings.Repeat(" ", depth), k.(string))
        printVal(v, depth+1)
    }
}

func printSlice(slc []interface{}, depth int) {
    for _, v := range slc {
        printVal(v, depth+1)
    }
}

func main() {

    m := make(map[interface{}]interface{})

    for _, data := range testData {

        yamlData := bytes.NewReader([]byte(data))
        decoder := yaml.NewDecoder(yamlData)

        for decoder.Decode(&m) == nil {
            printMap(m, 0)
            m = make(map[interface{}]interface{})

        }
    }
}
  • 写回答

1条回答 默认 最新

  • duangu4980 2019-02-21 15:37
    关注

    jsonlines is newline delimited JSON. That means the individual lines are JSON, but not multiple lines and certainly not a whole file of multiple lines.

    You will need to read the jsonlines input a line at a time, and those lines you should be able to process with go yaml, since YAML is a superset of JSON.

    Since you also seem to have YAML end of indicator (---) lines in your test, you need to process those as well.

    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器