在golang中解析多个JSON对象

时间:2018-05-15 12:17:39

标签: json go

我在golang中有一个与json解析相关的问题。 使用encoding / json包可以很容易地解析下面的对象。

[ 
    {"something":"foo"},
    {"something-else":"bar"}
]

我遇到的麻烦是当服务器返回多个dicts时 -

{"something":"foo"}
{"something-else":"bar"}

无法使用以下代码对其进行解析。

correct_format := strings.Replace(string(resp_body), "}{", "},{", -1)
json_output := "[" + correct_format + "]"

我正在尝试解析commoncrawl数据。 - For example

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

假设您的输入实际上是一系列有效的JSON文档,请使用json.Decoder对其进行解码:

package main

import (
    "encoding/json"
    "fmt"
    "io"
    "log"
    "strings"
)

var input = `
{"foo": "bar"}
{"foo": "baz"}
`

type Doc struct {
    Foo string
}

func main() {
    dec := json.NewDecoder(strings.NewReader(input))
    for {
        var doc Doc

        err := dec.Decode(&doc)
        if err == io.EOF {
            // all done
            break
        }
        if err != nil {
            log.Fatal(err)
        }

        fmt.Printf("%+v\n", doc)
    }
}

游乐场:https://play.golang.org/p/ANx8MoMC0yq

如果您的输入确实是您在问题中显示的内容,那么这不是JSON,您必须编写自己的解析器。

答案 1 :(得分:1)

似乎每一行都是它自己的json对象。

您可以使用以下代码将此输出结构化为正确的json:

package main

import (
    "fmt"
    "strings"
)

func main() {
    base := `{"trolo":"lolo"}
{"trolo2":"lolo2"}`

    delimited := strings.Replace(base, "\n", ",", -1)

    final := "[" + delimited + "]"
    fmt.Println(final)
}

您现在可以encoding/json使用final库。

答案 2 :(得分:0)

另一种选择是逐行解析每个传入的行,然后将每个传入的行添加到代码中的集合(即切片)Go为此提供一行scanner

yourCollection := []yourObject{}
scanner := bufio.NewScanner(YOUR_SOURCE)
for scanner.Scan() {
    obj, err := PARSE_JSON_INTO_yourObject(scanner.Text())
    if err != nil {
       // something
    }
    yourCollection = append(yourCollection, obj)
}
if err := scanner.Err(); err != nil {
    fmt.Fprintln(os.Stderr, "reading standard input:", err)
}

答案 3 :(得分:0)

您可以从文件中逐行读取ndjson并进行解析,然后对其进行逻辑运算。在下面的示例中,我使用了JSON字符串数组,而不是从文件中读取。

import (
    "encoding/json"
    "fmt"
)

type NestedObject struct {
    D string
    E string
}

type OuterObject struct {
    A string
    B string
    C []NestedObject
}

func main() {

    myJsonString := []string{`{"A":"1","B":"2","C":[{"D":"100","E":"10"}]}`, `{"A":"11","B":"21","C":[{"D":"1001","E":"101"}]}`}
    for index, each := range myJsonString {
        fmt.Printf("Index value [%d] is [%v]\n", index, each)
        var obj OuterObject
        json.Unmarshal([]byte(each), &obj)
        fmt.Printf("a: %v, b: %v, c: %v", obj.A, obj.B, obj.C)
        fmt.Println()
    }
}

输出:

Index value [0] is [{"A":"1","B":"2","C":[{"D":"100","E":"10"}]}]
a: 1, b: 2, c: [{100 10}]
Index value [1] is [{"A":"11","B":"21","C":[{"D":"1001","E":"101"}]}]
a: 11, b: 21, c: [{1001 101}]

Try it on golang play