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

时间:2015-02-21 08:47:12

标签: json 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)
}

但我不确定如何迭代数组条目中的键/值对。它是一个很好的,简洁的图书馆,但似乎没有很多例子,我的golang专业知识目前有限。

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

2 个答案:

答案 0 :(得分:2)

您可以使用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)
}

然而在那个例子中,simplejson是一种矫枉过正,使用struct / stdlib更有效。

为了完整起见,std lib版本:

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)查看其外观。

答案 1 :(得分:1)

使用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 {}表示法,这通常被认为是不好的做法。如果您的真实数据有任何类型声明,则应创建具有适当类型声明的新结构。