Распаковка сложного JSON в структуру и доступ к данным (срез среза) - PullRequest
0 голосов
/ 29 ноября 2018

Я уже некоторое время ломаю голову об этом.У меня есть файл JSON, который должен быть в следующем формате, который мне нужно перебирать и использовать операторы IF в Go:

[
[
    {
        "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 или цикл по элементам в ключе конфигурации!

Оператор IF игнорируется в цикле for (см. Код ниже)

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 на консоль для конфигурации с именем customerAndUser

Что должно быть напечатано:

New customer added
hi test 1
added 1

Спасибо за помощь

1 Ответ

0 голосов
/ 29 ноября 2018

Конфигурация JSON очень пахнет.Структура содержит configName и config - это две отдельные структуры в срезе.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)
        }
    }
}
...