使用Go语言中的struct解析嵌套的JSON。

huangapple go评论93阅读模式
英文:

parse nested json using struct in go language

问题

无法使用Go语言将嵌套的JSON解析为结构对象。

我有一个嵌套的JSON字符串,我想使用Go语言中的结构体解析它。JSON的格式如下所示:

{"action":"add","business":{"ListId":123,"ObjectTags":[{"tagCode":"csharp","tagName":"codename","tagValue":["2"],"tagType":3},{"tagCode":"goLang","tagName":"coding","tagValue":["3"],"tagType":3}]}}

我想使用Go语言解析JSON。
由于JSON具有嵌套结构,所以我按照下面的代码创建了结构体:

package main

import (
	"encoding/json"
	"fmt"
)


type ObjectTagsList struct {
	tagCode  string
	tagName  string
	tagValue []string
}

type Model struct {
	Action   string `json:"action"`
	Business struct {
		ListId     int64  `json:"ListId"`
		ObjectTags []ObjectTagsList `json:"ObjectTags"`
	} `json:"business"`
}

func main() {
	Json := `{"action":"add","business":{"ListId":123,"ObjectTags":[{"tagCode":"csharp","tagName":"codename","tagValue":["2"],"tagType":3},{"tagCode":"goLang","tagName":"coding","tagValue":["3"],"tagType":3}]}}`

	var model Model
	json.Unmarshal([]byte(Json), &model)

	fmt.Println(model.Action) // 正确打印为 "add"
	fmt.Println(model.Business.ListId) // 正确打印为 "123"


	fmt.Println(model.Business.ObjectTags) // 这里不会打印ObjectTags。而是打印为 "[{  []} {  []}]"


}

我无法获取内部嵌套JSON的值到结构体中

我还尝试将内部结构再次解组为

var object []ObjectTagsList

// 这会报错,因为无法将model.Business.ObjectTags(类型为[]ObjectTagsList的变量)转换为[]byte类型
json.Unmarshal([]byte(model.Business.ObjectTags), &object)

// 错误:无法将model.Business.ObjectTags(类型为[]ObjectTagsList的变量)转换为[]byte类型
fmt.Println(object)

这给我报错错误信息为无法将model.Business.ObjectTags类型为[]ObjectTagsList的变量转换为[]byte类型

如何将此JSON映射到结构体中
我希望以这样的方式映射以便我可以使用对象例如

model.Business.ObjectTags[0].tagCode //---> 应该打印/存储为 "csharp"
model.Business.ObjectTags[0].tagValue[0] //---> 应该打印/存储为 "2"

请帮忙解决

<details>
<summary>英文:</summary>

Unable to parse nested json into structs objects using go lang

I have a nested json string that I want to parse using struct in Go language. The json looks like this

{"action":"add","business":{"ListId":123,"ObjectTags":[{"tagCode":"csharp","tagName":"codename","tagValue":["2"],"tagType":3},{"tagCode":"goLang","tagName":"coding","tagValue":["3"],"tagType":3}]}}


I want to parse the json using GO language.
The json has nested structure so I created the structs as mentioned in the below code
package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
)
type ObjectTagsList struct {
tagCode  string
tagName  string
tagValue []string
}
type Model struct {
Action   string `json:&quot;action&quot;`
Business struct {
ListId     int64  `json:&quot;ListId&quot;`
ObjectTags []ObjectTagsList `json:&quot;ObjectTags&quot;`
} `json:&quot;business&quot;`
}
func main() {
Json := `{&quot;action&quot;:&quot;add&quot;,&quot;business&quot;:{&quot;ListId&quot;:123,&quot;ObjectTags&quot;:[{&quot;tagCode&quot;:&quot;csharp&quot;,&quot;tagName&quot;:&quot;codename&quot;,&quot;tagValue&quot;:[&quot;2&quot;],&quot;tagType&quot;:3},{&quot;tagCode&quot;:&quot;goLang&quot;,&quot;tagName&quot;:&quot;coding&quot;,&quot;tagValue&quot;:[&quot;3&quot;],&quot;tagType&quot;:3}]}}`
var model Model
json.Unmarshal([]byte(Json), &amp;model)
fmt.Println(model.Action) // This prints correctly as &quot;add&quot;
fmt.Println(model.Business.ListId) // This prints correctly as &quot;123&quot;
fmt.Println(model.Business.ObjectTags) // THIS DOES NOT PRINT THE ObjectTags. Rather this prints the ObjectTags as &quot;[{  []} {  []}]&quot;
}
I am unable to get the value of inner nested json into the structure.
I also tried unmarshalling the inner structure again as 
var object []ObjectTagsList
//This gives error as cannot convert model.Business.ObjectTags (variable of type []ObjectTagsList) to type []byte
json.Unmarshal([]byte(model.Business.ObjectTags), &amp;object) 
//error as cannot convert model.Business.ObjectTags (variable of type []ObjectTagsList) to type []byte
fmt.Println(object)
And this gives me an error as 
cannot convert model.Business.ObjectTags (variable of type []ObjectTagsList) to type []byte.
How do I map this json into the struct ?
I want to map this in such a way that I can use the objects like 
model.Business.ObjectTags[0].tagCode //--&gt; Should print/store &quot;csharp&quot;
model.Business.ObjectTags[0].tagValue[0] //--&gt; Should print/store &quot;2&quot;
Please help 
</details>
# 答案1
**得分**: 2
你只能对“导出”字段进行编组/解组,也就是说,只能对在当前包之外可访问的字段进行操作,而在Go语言中,这意味着“以大写字母开头的字段”。因此,如果你将代码修改为以下形式:
```go
package main
import (
"encoding/json"
"fmt"
)
type ObjectTagsList struct {
TagCode  string
TagName  string
TagValue []string
}
type Model struct {
Action   string `json:"action"`
Business struct {
ListId     int64            `json:"ListId"`
ObjectTags []ObjectTagsList `json:"ObjectTags"`
} `json:"business"`
}
func main() {
Json := `
{
"action": "add",
"business": {
"ListId": 123,
"ObjectTags": [
{
"tagCode": "csharp",
"tagName": "codename",
"tagValue": [
"2"
],
"tagType": 3
},
{
"tagCode": "goLang",
"tagName": "coding",
"tagValue": [
"3"
],
"tagType": 3
}
]
}
}
`
var model Model
json.Unmarshal([]byte(Json), &model)
fmt.Println(model.Action)
fmt.Println(model.Business.ListId)
fmt.Println(model.Business.ObjectTags)
}

你将得到以下输出:

add
123
[{csharp codename [2]} {goLang coding [3]}]

在这里,我们利用了json模块会自动将名为tagCode的键映射到名为TagCode的结构字段的特性,但实际上我们应该明确指定:

type ObjectTagsList struct {
	TagCode  string   `json:"tagCode"`
	TagName  string   `json:"tagName"`
	TagValue []string `json:"tagValue"`
}
英文:

You can only marshal/unmarshal "exported" fields -- that is, fields that are accessible outside of the current package, which in Go means "fields that start with a capital letter". So if you were to modify your code to look like this:


package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
)
type ObjectTagsList struct {
TagCode  string
TagName  string
TagValue []string
}
type Model struct {
Action   string `json:&quot;action&quot;`
Business struct {
ListId     int64            `json:&quot;ListId&quot;`
ObjectTags []ObjectTagsList `json:&quot;ObjectTags&quot;`
} `json:&quot;business&quot;`
}
func main() {
Json := `
{
&quot;action&quot;: &quot;add&quot;,
&quot;business&quot;: {
&quot;ListId&quot;: 123,
&quot;ObjectTags&quot;: [
{
&quot;tagCode&quot;: &quot;csharp&quot;,
&quot;tagName&quot;: &quot;codename&quot;,
&quot;tagValue&quot;: [
&quot;2&quot;
],
&quot;tagType&quot;: 3
},
{
&quot;tagCode&quot;: &quot;goLang&quot;,
&quot;tagName&quot;: &quot;coding&quot;,
&quot;tagValue&quot;: [
&quot;3&quot;
],
&quot;tagType&quot;: 3
}
]
}
}
`
var model Model
json.Unmarshal([]byte(Json), &amp;model)
fmt.Println(model.Action)
fmt.Println(model.Business.ListId)
fmt.Println(model.Business.ObjectTags)
}

You would get as output:

add
123
[{csharp codename [2]} {goLang coding [3]}]

Here we're taking advantage of the fact that the json module will automatically map a key named tagCode to a struct field named TagCode, but really we should be explicit:

type ObjectTagsList struct {
TagCode  string   `json:&quot;tagCode&quot;`
TagName  string   `json:&quot;tagName&quot;`
TagValue []string `json:&quot;tagValue&quot;`
}

huangapple
  • 本文由 发表于 2023年3月30日 11:24:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75883854.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定