如何使用 go-simplejson 遍历 json 文件

how do you traverse a json file using go-simplejson

我有一个 JSON 格式的文件:

{
  "data": {
    "docs": [
      {"key00": "val00", "key01": "val01"},
      {"key10": "val10", "key11": "val11"}
    ]
  }
}

我想将其转换为单独的 JSON 文档:

file0.json

{
  {"key00": "val00", "key01": "val01"}
}

file1.json

{
   {"key10": "val10", "key11": "val11"}
}

我可以使用以下方法枚举数组内容:

j, _ := ioutil.ReadFile(path)
dec, _ := simplejson.NewFromReader(bytes.NewReader(j))
for i,v := range dec.Get("data").Get("docs").MustArray() {
  out := simplejson.New()

  /* ??? move dec key/value pairs to out ??? */

  b, _ := out.EncodePretty()
  ioutil.WriteFile(outpath, b, 0777)
}

但我不确定如何遍历数组条目中的 key/value 对。这是一个不错、简洁的库,但似乎没有很多示例,而且我的 golang 专业知识目前有限。

任何帮助将不胜感激..谢谢!

您可以使用 simplejson.Set:

for _, doc := range dec.Get("data").Get("docs").MustArray() {
    out := simplejson.New()
    // doc is an interface{} holding a map, we have to type assert it.
    for k, v := range doc.(map[string]interface{}) {
        out.Set(k, v)
    }
    b, _ := out.EncodePretty()
    fmt.Printf("%s\n", b)
}

但是在那种情况下,简单json 是一种矫枉过正,使用结构/标准库更有效。

为了完整起见,标准库版本:

type DataLayout struct {
    Data struct {
        Docs []map[string]string `json:"docs"`
    } `json:"data"`
}

func main() {
    var in DataLayout
    err := json.NewDecoder(strings.NewReader(j)).Decode(&in)
    if err != nil {
        log.Fatal(err)
    }
    for _, doc := range in.Data.Docs {
        b, err := json.MarshalIndent(doc, "", "\t")
        if err != nil {
            log.Fatal(err)
        }
        fmt.Printf("%s\n", b)
    }
}

play

备注:

  • 你的json例子是错误的,"key10", "val10"应该是"key10": "val10"
  • 当您对数据结构的外观有疑问并且懒得阅读代码时,请使用 fmt.Printf("%#v", doc) 查看它的外观。

使用 simplejson 有什么具体原因吗? standard JSON library.

可以完成很多编码

使用标准库你可以这样解决你的问题:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
)

type Document struct {
    Data DataStruct
}

type DataStruct struct {
    Docs []interface{}
}

func main() {
    doc, err := ioutil.ReadFile("./doc.json")
    if err != nil {
        panic(err)
    }
    var document Document
    err = json.Unmarshal(doc, &document)
    if err != nil {
        panic(err)
    }
    for index := range document.Data.Docs {
        b, err := json.Marshal(document.Data.Docs[index])
        if err != nil {
            panic(err)
        }
        err = ioutil.WriteFile(fmt.Sprintf("file%d.json", index), b, 0777)
        if err != nil {
            panic(err)
        }
        fmt.Println(string(b))
    }
}

示例代码将为您提供两个文件,内容如下:

{"key00":"val00","key01":"val01"}

{"key10":"val10","key11":"val11"}

但是,如果您注意到我在 DataStruct 中使用了 []interface{} 符号,这通常被认为是不好的做法。如果您的真实数据有任何类型,您应该创建一个具有适当类型声明的新结构。