Golang解析多层嵌套结构体的JSON数据

Golang解析多层嵌套结构体的JSON数据 我有一个包含多个结构体的JSON格式数据

在一个复杂的结构体中

type MainJSON []struct {
	NestedInMain []struct {
		Type       string `json:"type"`
		NestedInNested []struct {
			Type        string        `json:"type"`
			Points [][]float64   `json:"points"`
			Label       string        `json:"label"`
		} `json:"geometries"`
		Time  string `json:"time"`
	} `json:"paths"`
	Name        string        `json:"name"`
	Description string        `json:"description"`
	Rating      string        `json:"rating"`
	Prepared    bool          `json:"Prepared"`
}

我将其拆分为多个结构体

  type MainJson []struct {
	NSIM NestedInMain
	Name        string        `json:"name"`
	Description string        `json:"description"`
	Rating      string        `json:"rating"`
	Prepared    bool          `json:"Prepared"`
}

type NestedInMain []struct {
	NIN NestedInNested
	Type string `json:"type"`
	Time string `json:"time"`
}

type NestedInNested []struct {
	Type   string      `json:"type"`
	Points [][]float64 `json:"points"`
	Label  string      `json:"label"`
} 

当我执行以下操作时

iap := MainJson{}
err := json.Unmarshal([]byte(test), &iap)
if err != nil {
	fmt.Println(err)
	return
}
log.Println(iap)

我无法访问第一个和第二个嵌套结构体及其字段 (iap.NSIM) 或 (iap.NSIM.NIN.Label) 如何正确实现这个功能? 稍后我想从response.body获取json

谢谢!!!


更多关于Golang解析多层嵌套结构体的JSON数据的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

那个 JSON 无效。

但如果我直接去掉外层括号,它就是一个有效的 [][2]int 表示形式。

更多关于Golang解析多层嵌套结构体的JSON数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


YongGopher:

NestedInMain

NestedInMain 字段带有 json:"paths" 标签,您遗漏了它

谢谢! 但如何让它更简单呢? 因为JSON返回给我的是成对数组——我想按相同顺序发送到Go切片中 例如JSON

{
 [
  [1, 2],
  [3, 4],
  [5, 6]
 ]
}

错误提示表明你的类型没有该字段。你的类型是一个指向Test结构体切片的指针。

你想要访问Test结构体内部的某个字段……但具体是哪一个呢?你的JSON提供了多个字段,因此需要使用切片(请移除指向切片的指针)。

你可能需要遍历JSON中包含的每个Test结构体并提取值:

nT[i].NS[j].NST[k].NestedThird[y]

应该会如你所期望的那样返回一对a, b值。

我尝试了但这个方法不行 这是我的JSON示例

[
    {
        "First": [],
        "Nested": [
            {
                "Type": "type",
                "Text": "text",
                "NestedSecond": [
                    {
                        "Type": "typetwo",
                        "Name": "nametwo",
                        "NestedThird": [
                            [
                                46.203362,
                                2.5699142
                            ],
                            [
                                46.202634, 
                                2.5721897
                            ]
                        ]
                    }
                ]
            }
        ],
        "tags": [],
        "name": "someName"
    }
]

当我运行这段代码时

package main

import (
	"encoding/json"
	"log"
	"os"
)

type Test struct {
	First []interface{} `json:"First"`
	NS    []*Nested     `json:"Nested"`
	Tags  []interface{} `json:"tags"`
	Name  string        `json:"name"`
}

type Nested struct {
	Type string          `json:"Type"`
	Text string          `json:"Text"`
	NST   []*NestedSecond `json:"NestedSecond"`
}

type NestedSecond struct {
	Type        string      `json:"Type"`
	Name        string      `json:"Name"`
	NestedThird [][]float64 `json:"NestedThird"`
}

var nT *[]Test

func main() {
	file, _ := os.Open("test2.json")
	decoder := json.NewDecoder(file)

	err := decoder.Decode(&nT)
	if err != nil {
		log.Panic(err)
	}

	log.Println(nT)
}

显示结果为 &[{[] [0xc420092080] [] someName}]

但是我无法访问 log.Println(&nT.NS)

返回错误 nT.NS undefined (type *[]Test has no field or method NS)

最后我想要将NestedThird分成两个变量a和b

a = 46.202634
b = 2.5699142

问题在于您的结构体定义没有正确映射JSON的嵌套关系。JSON字段paths对应的是一个数组,但您将其定义为单个NSIM字段。以下是正确的实现方式:

type MainJSON []struct {
    Paths        []NestedInMain `json:"paths"`
    Name         string         `json:"name"`
    Description  string         `json:"description"`
    Rating       string         `json:"rating"`
    Prepared     bool           `json:"Prepared"`
}

type NestedInMain struct {
    Type       string            `json:"type"`
    Geometries []NestedInNested  `json:"geometries"`
    Time       string            `json:"time"`
}

type NestedInNested struct {
    Type   string      `json:"type"`
    Points [][]float64 `json:"points"`
    Label  string      `json:"label"`
}

使用示例:

func main() {
    jsonData := `[
        {
            "paths": [
                {
                    "type": "path1",
                    "geometries": [
                        {
                            "type": "line",
                            "points": [[1.0, 2.0], [3.0, 4.0]],
                            "label": "segment1"
                        }
                    ],
                    "time": "2023-01-01"
                }
            ],
            "name": "test",
            "description": "test description",
            "rating": "5",
            "Prepared": true
        }
    ]`

    var data MainJSON
    err := json.Unmarshal([]byte(jsonData), &data)
    if err != nil {
        log.Fatal(err)
    }

    // 访问嵌套字段
    if len(data) > 0 {
        mainItem := data[0]
        fmt.Println("Name:", mainItem.Name)
        
        if len(mainItem.Paths) > 0 {
            path := mainItem.Paths[0]
            fmt.Println("Path Type:", path.Type)
            fmt.Println("Time:", path.Time)
            
            if len(path.Geometries) > 0 {
                geometry := path.Geometries[0]
                fmt.Println("Geometry Type:", geometry.Type)
                fmt.Println("Label:", geometry.Label)
                fmt.Println("Points:", geometry.Points)
            }
        }
    }
}

从HTTP响应读取JSON:

func fetchAndParseJSON(url string) (MainJSON, error) {
    resp, err := http.Get(url)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()

    var data MainJSON
    err = json.NewDecoder(resp.Body).Decode(&data)
    return data, err
}

这样您就可以正确访问所有嵌套结构体的字段:data[0].Paths[0].Geometries[0].Label

回到顶部