Golang解析JSON响应的方法与技巧

Golang解析JSON响应的方法与技巧 我想解析命令的执行结果

az account list-locations

这个命令返回一个JSON响应

https://pastebin.com/raw/jeZ4LMP2

我需要列出所有可用的Microsoft Azure区域。

我是Golang新手,以下是我目前完成的代码:

package main

import "fmt"
import "os"
import "os/exec"
import "encoding/json"

type AzureLocation struct {
	displayName string
	id string
	latitude string
	longitude string
	name string
	subscriptionId string
}

func main() {

	cmdOut, err := exec.Command("az", "account", "list-locations").Output()
	
	if (err != nil) {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	bytes := cmdOut

	var azureLocations []AzureLocation
	json.Unmarshal(bytes, &azureLocations)

	fmt.Println(string(azureLocations));
}

有人能帮我打印所有区域吗?我需要遍历数组并打印displayName和name字段。


更多关于Golang解析JSON响应的方法与技巧的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

正如错误信息所示,err 变量已被声明,不能重复声明。请将 := 改为 = 进行赋值操作。

更多关于Golang解析JSON响应的方法与技巧的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好。是完全不同还是只是某些字段没有填充?

感谢您的回复,这正是我需要的,但我需要从命令行读取字符串。考虑到您可能没有安装 Azure CLI,我尝试用 URL 替换 JSON 数据源,以下是代码:

func main() {
    fmt.Println("hello world")
}

能否请您告诉我为什么会出现以下错误:

prog.go:39:6: no new variables on left side of :=

谢谢,问题已经解决了。

有时候 Azure CLI 会返回不同类型的 JSON 对象。例如,当我创建虚拟机时,如果成功,它会返回一种包含服务器 IP、服务器名称等信息的 JSON 字符串;如果由于某些原因失败,返回的 JSON 字符串结构则不同。我应该如何处理这种情况?

我不太确定具体需要什么。只需遍历你的切片并打印字段值即可。

示例:https://play.golang.org/p/js0A9elNJl-

package main

import "fmt"

type MyStruct struct {
	Field1 string
	Field2 int
}

func main() {
	slice := []MyStruct{
		{"A", 1},
		{"B", 2},
		{"C", 3},
	}

	for i, v := range slice {
		fmt.Printf("索引 %d: 字段1=%s, 字段2=%d\n", i, v.Field1, v.Field2)
	}
}

可以创建一个合并这两个响应的结构体:

type Reply struct {
	Fqdns            string `json:"fqdns"`
	ID               string `json:"id"`
	Location         string `json:"location"`
	MacAddress       string `json:"macAddress"`
	PowerState       string `json:"powerState"`
	PrivateIPAddress string `json:"privateIpAddress"`
	PublicIPAddress  string `json:"publicIpAddress"`
	ResourceGroup    string `json:"resourceGroup"`
	Zones            string `json:"zones"`
	Error            struct {
		Code    string `json:"code"`
		Message string `json:"message"`
	} `json:"error"`
}

然后检查 Error.Code 是否为空字符串。

这对我来说还是有点不太清楚。如果在任何情况下,你只需要从响应的特定字段中获取值,那么使用专门的库会更合适。

例如这个库:https://github.com/thedevsaddam/gojsonq

代码:

package main

import (
	"fmt"

	"github.com/thedevsaddam/gojsonq"
)

var jsonData string = `[
  {
    "displayName": "East Asia",
    "id": "/subscriptions/da87b641-e192-4863-a66a-40e11b8741f7/locations/eastasia",
    "latitude": "22.267",
    "longitude": "114.188",
    "name": "eastasia",
    "subscriptionId": null
  },
  {
    "displayName": "Southeast Asia",
    "id": "/subscriptions/da87b641-e192-4863-a66a-40e11b8741f7/locations/southeastasia",
    "latitude": "1.283",
    "longitude": "103.833",
    "name": "southeastasia",
    "subscriptionId": null
  }]`

func main() {
	data := gojsonq.New().JSONString(jsonData).Only("name", "displayName")

	for i, t := range data.([]interface{}) {
		v := t.(map[string]interface{})
		fmt.Println(i, "=>", v["name"], v["displayName"])
	}
}

输出:

0 => eastasia East Asia
1 => southeastasia Southeast Asia

在Go语言中解析JSON响应时,需要确保结构体字段是可导出的(首字母大写),这样encoding/json包才能正确访问这些字段。以下是修正后的代码:

package main

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
)

type AzureLocation struct {
	DisplayName    string `json:"displayName"`
	ID             string `json:"id"`
	Latitude       string `json:"latitude"`
	Longitude      string `json:"longitude"`
	Name           string `json:"name"`
	SubscriptionID string `json:"subscriptionId"`
}

func main() {
	cmdOut, err := exec.Command("az", "account", "list-locations").Output()
	
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}

	var azureLocations []AzureLocation
	err = json.Unmarshal(cmdOut, &azureLocations)
	if err != nil {
		fmt.Fprintln(os.Stderr, "JSON解析错误:", err)
		os.Exit(1)
	}

	for _, location := range azureLocations {
		fmt.Printf("DisplayName: %s, Name: %s\n", location.DisplayName, location.Name)
	}
}

主要修改点:

  1. AzureLocation结构体的所有字段改为首字母大写,并添加JSON标签
  2. 添加了JSON解析错误处理
  3. 使用循环遍历切片并打印所需的字段
  4. 移除了无效的string(azureLocations)转换

运行此代码将输出所有Azure区域的displayName和name字段。

回到顶部