解析嵌套的json文件

时间:2019-03-03 17:29:24

标签: json go

我正在解析具有以下异常结构的JSON文件:

{
    "394885": 
    {
        "record": 
        {
            "student_name": "Daryl Jones",
            "student_number": 123884,
            "student_dob": "12/10/1982",
            "student_email": "djones@school.ac.uk",
        }    
    },
}

我一直在进行一些代码演示,但我想将其全部放入一个struct中,然后计划通过一个数字字符串(它是我猜得出的对象名称)进行搜索?

我不擅长JSON或Go,这是我到目前为止编写的代码:

package main

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

type id struct {
    recordid string
    record   []record
}

type record struct {
    name   string
    number uint32
    dob    string
    email  string
}

func main() {
    jsonFile, err := os.Open("/home/emyrw/development/go/src/json_processor/demo.json")
    if err != nil {
        fmt.Println(err)
    } else {
        var records id

        byteValue, _ := ioutil.ReadAll(jsonFile)
        json.Unmarshal(byteValue, &records)
        fmt.Println(records)

        fmt.Println("opened demo.json")
        defer jsonFile.Close()
    }
}

我不确定我是否正确,但是会重视任何人所能提供的任何技巧或建议。我一直在使用Google搜索,但是找不到适合我的情况的样本。

4 个答案:

答案 0 :(得分:2)

首先,您的JSON无效。 与GoLang结构不同,您无需在最终对象后放置mechanic_id

{     “ 394885”:     {         “记录”:         {             “ student_name”:“ Daryl Jones”,             “学生人数”:123884,             “ student_dob”:“ 12/10/1982”,             “ student_email”:“ djones@school.ac.uk”         }
    } }

第二, ,应该通过对结构中的字段进行精确命名(使用JSON对象中命名的字段)或使用属性来对JSON进行精确建模。

您的JSON的外部类型不是var records,而是类型id

map[string]id没有id字段,但是有recordid字段,但是,如果以下情况必须导出结构的字段(以大写字母开头):您想将JSON序列化到其中。

这是属性派上用场的地方,

record

type id struct { Record []record `json:"record"` } 结构相同,

record

第三, 打开文件后,您立即放置了type record struct { Name string `json:"student_name"` Email string `json:"student_email"` // You get the idea... } 语句, 将其放在方块末尾会破坏目的。

答案 1 :(得分:2)

声明与数据结构匹配的Go类型。 JSON数据具有三个级别的对象。使用映射表示JSON中的顶级对象,因为顶级对象具有任意键。对JSON中的低级对象使用结构。

使用JSON字段标签将JSON中使用的蛇案名称映射到更惯用的Go名称。 Export字段,以便JSON包可以访问它们。

请参阅Marshal函数文档,以获取有关json / encoding包如何使用字段标记以及导出字段的要求的信息。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    bool LeftControl = false;
    bool LeftShift = false;
    bool LeftAlt = false;
    // Update is called once per frame
    void Update()
    {
        LeftControl = Input.GetKey(KeyCode.LeftControl);
        LeftShift = Input.GetKey(KeyCode.LeftShift);
        LeftAlt = Input.GetKey(KeyCode.LeftAlt);

        if (LeftAlt || LeftShift) fb();
        else fa();
    }

    private void fb()
    {
        print("fb");
        if (LeftControl)
        {
            if (Input.GetKeyDown(KeyCode.Alpha1)) print("leftcontrol");
        }
        else
        {
            if (Input.GetKeyDown(KeyCode.Alpha1)) print("NOleftcontrol");
        }
    }

    private void fa()
    {
        print("fa");
        if (LeftControl)
        {
            if (Input.GetKeyDown(KeyCode.Alpha1)) print("leftcontrol");
        }
        else if(LeftShift)
        {
            if (Input.GetKeyDown(KeyCode.Alpha1)) print("leftshift");
        }
    }
}

Run it on the playground

答案 2 :(得分:0)

jsonquery包可以轻松地从JSON文档中提取数据,并且不依赖于已定义的struct对象。

func main() {
    s := `{
        "394885": 
        {
            "record": 
            {
                "student_name": "Daryl Jones",
                "student_number": 123884,
                "student_dob": "12/10/1982",
                "student_email": "djones@school.ac.uk"
            }    
        }
    }`
    doc, err := jsonquery.Parse(strings.NewReader(s))
    if err != nil {
        panic(err)
    }
    nodes := jsonquery.Find(doc, "*")
    for _, n := range nodes {
        fmt.Printf("id: %s \n", n.Data)
        name := jsonquery.FindOne(n, "//student_name") // Find student name node
        fmt.Printf("student name: %s\n", name.InnerText())
        number := jsonquery.FindOne(n, "//student_number") // Find node for student number
        fmt.Printf("student number: %s\n", number.InnerText())
    }
}

答案 3 :(得分:-1)

您可以将此结构用于ID类型

type id struct {
    record map[string]record
}

修改

这是具有一些解释的有效解决方案:

由于您具有多层json,因此可以将其解析为嵌套结构。

{
        "student_name": "Daryl Jones",
        "student_number": 123884,
        "student_dob": "12/10/1982",
        "student_email": "djones@school.ac.uk"
} 

要解析json的这一部分,您需要此结构

type record struct {
    Name   string `json:"student_name"`
    Number uint32 `json:"student_number"`
    Dob    string `json:"student_dob"`
    Email  string `json:"student_email"`
}

必须将字段导出(以大写字母开头),并具有与json属性匹配的json标签。

{
    "record": 
    {
        "student_name": "Daryl Jones",
        "student_number": 123884,
        "student_dob": "12/10/1982",
        "student_email": "djones@school.ac.uk"
    }    
}

要使该部分正常工作,您需要像这样的嵌套结构

type id struct {
     Record record
}

文件名将再次导出,但是由于它与您的json属性匹配,因此您不需要标签。

{
"394885": 
  {
    "record": 
    {
        "student_name": "Daryl Jones",
        "student_number": 123884,
        "student_dob": "12/10/1982",
        "student_email": "djones@school.ac.uk"
    }    
  }
}

由于顶级属性名称是学生ID,因此您可以使用地图代替结构

 var records map[string]id 

并确保您没有尾随逗号,因为这是json规范中不允许的