将复杂的JSON解组为结构并访问数据(slice of slices)

时间:2018-11-29 13:21:01

标签: json go slice

我已经为此花了一段时间。我有一个JSON文件,该文件必须具有以下格式,我需要对其进行迭代并在Go中使用IF语句:

[
[
    {
        "configName": "customer"
    },
    {
        "config": [
            {
                "emailSubject": "New customer added"
            },
            {
                "text": "Hi test 2"
            },
            {
                "text": "added 2"
            }
        ]
    }
]
[
    {
        "configName": "customerAndUser"
    },
    {
        "config": [
            {
                "emailSubject": "New customer added"
            },
            {
                "text": "Hi, test 1"
            },
            {
                "text": "added 1"
            }
        ]
    }
]
]

我想将其放入一个结构体中,像这样:

type Config [][]struct {
    configName string `json: configName`
    config     []struct {
        Text         string `json: text`
        EmailSubject string `json: emailSubject`
    } `json: config`
}

我可以很好地解组数据,就像这样:

configData, err := ioutil.ReadFile("testing-config.json")
if err != nil {
    fmt.Println(err)
}
var configDataUnmarshalled Config

json.Unmarshal([]byte(configData), &configDataUnmarshalled)

然后打印数据,这很好,但是这里有些奇怪:print语句返回我未指定要打印的项目的空白。这是我打印未编组数据时打印内容的示例:

从未整理的数据中打印输出:

[[{customer []} { [{ New customer added} {hi test 2 } {added 2 }]}] [{customerAndUser []} { [{ New customer added} {hi test 1 } {added 1 }]}]]

但是我似乎无法使用IF语句或循环遍历config键中的元素!

for循环中的IF语句被忽略(请参见下面的代码输出)

for _, configs := range configDataUnmarshalled {

    for _, configurations := range configs {

        fmt.Println("These are the top level elements in my struct: ", configurations.ConfigName)

        if configurations.ConfigName == "customerAndUser" {

            for _, config := range configurations.Config {

                fmt.Println(config)
            }
        }
    }
}

以下是打印内容:

These are the top level elements in my struct:  customer
These are the top level elements in my struct:
These are the top level elements in my struct:  customerAndUser
These are the top level elements in my struct:

从FOR循环中,您可以看到当配置具有特定名称(在这种情况下为“ customerAndUser”)时,我想访问数据

这里IF语句被完全忽略了

我想了解/解决两件事:

  1. 如何通过IF语句访问数据
  2. 为什么程序打印空白?

所需的输出将打印出emailSubject,并将两个Text元素的数据输出到配置为console的控制台,名称为customerAndUser

应打印的内容:

New customer added
hi test 1
added 1

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

json配置很难闻。包含configNameconfig的结构是切片中的两个单独的结构。 configName具有价值,因此config为空且倒退。像这样的json时可以使用。

{
        "configName": "customerAndUser",
        "config": [
            {
                "emailSubject": "New customer added"
            },
            {
                "text": "Hi, test 1"
            },
            {
                "text": "added 1"
            }
        ]
 }

因此,如果您不能更改json配置格式。这是解决方案

endUser := false

for _, configs := range configDataUnmarshalled {

    endUser = false
    for _, configurations := range configs {

        if configurations.ConfigName == "customerAndUser" {
            endUser = true
            continue
        }

        if !endUser || len(configurations.Config) == 0 {
            continue
        }

        for _, config := range configurations.Config {
            fmt.Println(config)
        }
    }
}