如何将嵌套的JSON解析为Go中的结构?

时间:2015-12-01 07:41:40

标签: json go struct unmarshalling

如何将嵌套的JSON映射到嵌套的Struct,如下所示:

{
  key1: val1,
  key2: val2,
  chilDStruct1 : {
                     key3: val3,
                     key4: val4,
                }
  chilDStruct2 : {
                     key5: val5,
                     key6: val6,
                }
}

输入JSON:

var data MainStruct
    file, err := ioutil.ReadFile("jsonData.json")
    if err != nil {
        log.Fatal(err)
    }
    err = json.Unmarshal(file, &data)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(data.key1)

如何映射。我在Java中使用过jsonMapper但不知道如何在这里做。我尝试了这个,但这不起作用:

u := &MainStruct{}
file, err := ioutil.ReadFile("jsonData.json")
if err != nil {
    log.Fatal(err)
}
err = json.Unmarshal([]byte(file), u)
if err != nil {
    log.Fatal(err)
}
fmt.Println(u.key1)

我也尝试了这个:

0

但输出始终是public static void main(String[] args) { int num1 = 1; int num2 = 1; int result = num1 * num2; System.out.println("%d x %d = %d\n",num1,num2,result); }

1 个答案:

答案 0 :(得分:3)

您的示例中存在一些错误(包括JSON文本和源代码)。让我们解决它们。

JSON文本

首先你的JSON无效。试试这个而不是你的:

{
    "key1": "val1",
    "key2": "val2",
    "childStruct1" : {
        "key3": "val3",
        "key4": "val4"
    },
    "childStruct2" : {
        "key5": "val5",
        "key6": "val6"
    }
}

转到类型定义

其次,定义结构类型的Go源有语法错误。

第三,您必须按顺序导出struct字段,以便json包可以设置它们的值。试试这个而不是你的:

type ChildStruct1 struct {
    Key3 string
    Key4 string
}

type ChildStruct2 struct {
    Key4 string
    Key5 string
}

type MainStruct struct {
    Key1         string
    Key2         string
    ChildStruct1 ChildStruct1
    ChildStruct2 ChildStruct2
}

解析JSON文本的代码

现在开始解析JSON文本的代码。您可以使用ioutil.ReadFile()将整个文件读入内存,但通常更有效的是不读取整个文件,而是读取" stream"它到解码器(使用文件作为输入)。

os.Open()返回*File。它不是[]byte,而是实现io.Reader。因此,您无法将其传递给json.Unmarshal()。而是使用接受io.Reader的{​​{3}}创建json.Decoder,以便您可以传递打开的文件。并且不要忘记使用json.NewDecoder()关闭打开的文件,最好将其作为延迟语句关闭(如果打开它成功)。

f, err := os.Open("jsonData.json")
if err != nil {
    log.Panic(err)
}
defer f.Close()

var data MainStruct
err = json.NewDecoder(f).Decode(&data)
if err != nil {
    log.Panic(err)
}
fmt.Println(data.Key1)
fmt.Printf("%+v", data)

(请注意,我使用File.Close()代替log.Panic(),后者调用log.Fatal(),因此不会调用我们的延迟函数。)

输出:

val1
{Key1:val1 Key2:val2 ChildStruct1:{Key3:val3 Key4:val4} ChildStruct2:{Key4: Key5:val5}}

Go Playground的修改版

这是一个修改后的版本,它根据源代码中定义的常量解析JSON文本,在os.Exit()上尝试:

var data MainStruct
err := json.Unmarshal([]byte(input), &data)
if err != nil {
    log.Fatal(err)
}
fmt.Println(data.Key1)
fmt.Printf("%+v", data)

最后的笔记

JSON文本中的键以小写字母开头,Go开头的结构字段名称以大写字母开头(需要导出),但json包是"聪明"足以匹配他们。如果您使用不同的东西,可以使用Go Playground来指定如何在json中找到结构字段,例如。

type ChildStruct1 struct {
    Key3 string `json:"myKey3"`
    Key4 string `json:"myKey4"`
}