поддержка golang yaml для jsonlines - PullRequest
0 голосов
/ 21 февраля 2019

Я пытался получить пакет go yaml для анализа файла с записями jsonlines.

Ниже приведен простой пример с тремя вариантами анализа данных.

  • Первый вариант - это пример с несколькими документами yaml.Оба документа разбираются нормально.

  • Второй вариант - это пример с двумя jsonline.Первая строка анализируется нормально, но вторая пропущена.

  • Вариант третий - это пример с двумя jsonline, но я поместил разделители yaml doc между ними, чтобы вызвать проблему.Оба эти синтаксического анализа в порядке.

Из прочтения спецификаций yaml и json я считаю, что второй вариант, множественные jsonlines, должен обрабатываться парсером yaml.

Мои вопросы:

  • Должен ли YAML-парсер справляться с jsonlines?
  • Правильно ли я использую пакет go yaml?

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\n", "<null>")
    } else if typ.Kind() == reflect.Int || typ.Kind() == reflect.String {
        fmt.Printf("%s%v\n", strings.Repeat(" ", depth), v)
    } else if typ.Kind() == reflect.Slice {
        fmt.Printf("\n")
        printSlice(v.([]interface{}), depth+1)
    } else if typ.Kind() == reflect.Map {
        fmt.Printf("\n")
        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 Ответ

0 голосов
/ 21 февраля 2019

jsonlines - это символ JSON, разделенный символом новой строки.Это означает, что отдельные строки - это JSON, но не несколько строк и, конечно, не целый файл из нескольких строк.

Вам нужно будет читать входные строки jsonlines за раз, и эти строки вы должны иметь возможностьобработайте с помощью go yaml, поскольку YAML - это расширенный набор JSON.

Поскольку в вашем тесте также есть строки индикатора конца YAML (---), вам также необходимо обработать их.

...