恐慌:json:如何在Golang中解组嵌套的JSON数组

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

panic: json: How to unmarshall nested json array in Golang

问题

我遇到了一个解析嵌套JSON数组的问题。以下是示例:

{
  "Subnets": [
    {
      "AvailabilityZone": "xx",
      "AvailabilityZoneId": "xx",
      "AvailableIpAddressCount": 173,
      "CidrBlock": "xx",
      "DefaultForAz": "xx",
      "MapPublicIpOnLaunch": "xx",
      "MapCustomerOwnedIpOnLaunch": "xx",
      "State": "xx",
      "SubnetId": "xx",
      "VpcId": "xx",
      "OwnerId": "xx",
      "AssignIpv6AddressOnCreation": "xx",
      "Ipv6CidrBlockAssociationSet": [],
      "Tags": [
        {
          "Key": "Name",
          "Value": "xx"
        },
        {
          "Key": "workload",
          "Value": "xx"
        },
        {
          "Key": "xx",
          "Value": "xx"
        },
        {
          "Key": "aws:cloudformation:stack-name",
          "Value": "xx"
        },
        {
          "Key": "host_support_group",
          "Value": "xx"
        },
        {
          "Key": "environment",
          "Value": "xx"
        },
        {
          "Key": "client",
          "Value": "xx"
        },
        {
          "Key": "aws:cloudformation:stack-id",
          "Value": "xx"
        },
        {
          "Key": "application",
          "Value": "Subnet"
        },
        {
          "Key": "xx",
          "Value": "xx"
        },
        {
          "Key": "xx",
          "Value": "xx"
        },
        {
          "Key": "xx",
          "Value": "xx"
        },
        {
          "Key": "regions",
          "Value": "ca-central-1"
        }
      ],
      "SubnetArn": "xx"
    }
  ],
  "ResponseMetadata": {
    "RequestId": "xx",
    "HTTPStatusCode": 200,
    "HTTPHeaders": {
      "x-amzn-requestid": "xx",
      "cache-control": "no-cache, no-store",
      "strict-transport-security": "max-age=31536000; includeSubDomains",
      "content-type": "text/xml;charset=UTF-8",
      "content-length": "3176",
      "vary": "accept-encoding",
      "date": "xx",
      "server": "AmazonEC2"
    },
    "RetryAttempts": 0
  }
}

我只想要"AvailableIpAddressCount"的值,我尝试使用interface{},但无法获取所需的值。这是Golang playground的链接 - playground

错误-
我使用interface{}时遇到了这个错误

是否有其他方法可以从JSON对象中提取"AvailableIpAddressCount"的值?

感谢任何帮助或参考资料。

英文:

I'm having trouble unmarshalling a nested json array. Sample below:

{
"Subnets": [
{
"AvailabilityZone": "xx",
"AvailabilityZoneId": "xx",
"AvailableIpAddressCount": 173,
"CidrBlock": "xx",
"DefaultForAz": "xx",
"MapPublicIpOnLaunch": "xx",
"MapCustomerOwnedIpOnLaunch": "xx",
"State": "xx",
"SubnetId": "xx",
"VpcId": "xx",
"OwnerId": "xx",
"AssignIpv6AddressOnCreation": "xx",
"Ipv6CidrBlockAssociationSet": [],
"Tags": [
{
"Key": "Name",
"Value": "xx"
},
{
"Key": "workload",
"Value": "xx"
},
{
"Key": "xx",
"Value": "xx"
},
{
"Key": "aws:cloudformation:stack-name",
"Value": "xx"
},
{
"Key": "host_support_group",
"Value": "xx"
},
{
"Key": "environment",
"Value": "xx"
},
{
"Key": "client",
"Value": "xx"
},
{
"Key": "aws:cloudformation:stack-id",
"Value": "xx"
},
{
"Key": "application",
"Value": "Subnet"
},
{
"Key": "xx",
"Value": "xx"
},
{
"Key": "xx",
"Value": "xx"
},
{
"Key": "xx",
"Value": "xx"
},
{
"Key": "regions",
"Value": "ca-central-1"
}
],
"SubnetArn": "xx"
}]
,
"ResponseMetadata": {
"RequestId": "xx",
"HTTPStatusCode": 200,
"HTTPHeaders": {
"x-amzn-requestid": "xx",
"cache-control": "no-cache, no-store",
"strict-transport-security": "max-age=31536000; includeSubDomains",
"content-type": "text/xml;charset=UTF-8",
"content-length": "3176",
"vary": "accept-encoding",
"date": "xx",
"server": "AmazonEC2"
},
"RetryAttempts": 0
}
}

The only value I want is "AvailableIpAddressCount", I tried using interface{} but I'm not able to get the necessary value. Here's the Golang playground link - playground

Error-
I'm getting this error using interface{}

Is there any other way to extract just the "AvailableIpAddressCount" value from the json object?

Any help or references are appreciated.

答案1

得分: 3

你可以创建一个具有所需字段的结构体,并使用该结构体解组JSON字节,这将填充结构体中提到的字段。

type Something struct {
	AvailableIpAddressCount int `json:"AvailableIpAddressCount"`
}

var data Something
if err := json.Unmarshal(byt, &data); err != nil {
        panic(err)
}

AvailableIpAddressCount = data.AvailableIpAddressCount
英文:

You can create a struct with the desired field and unmarshal the JSON bytes using that struct which will populate fields mentioned in your struct.

type Something struct {
AvailableIpAddressCount int `json:"AvailableIpAddressCount"`
}
var data Something
if err := json.unmarshal(byt, &data); err != nil {
panic(err)
}
AvailableIpAddressCount = data.AvailableIpAddressCount

答案2

得分: 1

Go使用静态结构体来解码JSON,所以你可能需要创建一个包含至少你所需内容的结构体。如果你有了结构体,你可以像这样访问AvailableIPAddressCount

tmp.Subnets[0].AvailableIPAddressCount

这是一个示例代码的链接:https://play.golang.org/p/FsjeOubov1Q。

要从示例JSON创建JSON结构体,你可以使用像这个的工具。

如果你需要遍历所有子网:

for _, subnet := range tmp.Subnets {
    fmt.Println(subnet.AvailableIPAddressCount)
}

如果你想动态使用JSON,你也可以使用https://github.com/spf13/viper。但它可能比静态解码慢。

英文:

Go uses static structs to decode json, so you probably need to create a struct that contains at least what you are looking for. If you have your struct, you can access AvailableIPAddressCount like this:

tmp.Subnets[0].AvailableIPAddressCount

Here is the playground https://play.golang.org/p/FsjeOubov1Q.

To create json structs from example json you can use tools like this.

And if you need to loop through all subnets:

for _, subnet := range tmp.Subnets {
fmt.Println(subnet.AvailableIPAddressCount)
}

If you want to use json dynamically you can also use https://github.com/spf13/viper. But it's probably slower than statically decoding.

huangapple
  • 本文由 发表于 2021年9月7日 17:02:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/69085272.html
匿名

发表评论

匿名网友

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

确定