Как записать все декодированные данные в файл JSON? - PullRequest
0 голосов
/ 03 мая 2019

Я пытаюсь проанализировать данные XML в файл JSON, но когда я начинаю записывать маршалированные данные в файл JSON, он просто перезаписывает данные в файл JSON, и в результате у меня есть файл с последним элементом XML. Как записать все данные в файл JSON?

Фрагмент кода, который анализирует XML и данные маршала в JSON

    decoder := xml.NewDecoder(file)
    resultData := map[string]map[string]string{}
    for {
        t, _ := decoder.Token()
        if t == nil {
            break
        }

        switch et := t.(type) {
        case xml.StartElement:
            if et.Name.Local == "profile" {
                var object XMLProfile
                decoder.DecodeElement(&object, &et)

                resultData = map[string]map[string]string{
                    object.ProfileName: {},
                }

                for _, val := range object.Fields {
                    resultData[object.ProfileName][val.Name] = val.Value
                }
            }
        }
    }

    if out, err := json.MarshalIndent(resultData, "", "\t"); err != nil {
        panic(err)
    } else {
        _ = ioutil.WriteFile("test.json", out, 0644)
    }

Ожидайте JSON:

{
  "Profile 1": {
      "role": "user"
  },

  "Profile 2": {
      "role": "user"
  },

  "Profile 3": {
      "role": "admin"
  }
}

Фактический JSON:

{
  "Profile 3": {
    "role": "admin"
  }
}

1 Ответ

0 голосов
/ 03 мая 2019

Похоже, что вы воссоздаете resultData после каждой итерации в узлах с именем "profile". Как только это произойдет, только последний достигнет кода, в котором вы пишете JSON.

Попробуйте это:

decoder := xml.NewDecoder(file)
resultData := map[string]map[string]string{}
for {
    t, _ := decoder.Token()
    if t == nil {
        break
    }

    switch et := t.(type) {
    case xml.StartElement:
        if et.Name.Local == "profile" {
            var object XMLProfile
            decoder.DecodeElement(&object, &et)

            resultData[object.ProfileName] = map[string]string{}

            for _, val := range object.Fields {
                resultData[object.ProfileName][val.Name] = val.Value
            }
        }
    }
}

if out, err := json.MarshalIndent(resultData, "", "\t"); err != nil {
    panic(err)
} else {
    _ = ioutil.WriteFile("test.json", out, 0644)
}

Я бы также проверил, не появляется ли в XML повторяющееся ProfileName, так как оно переопределяет предыдущую запись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...