如何通过遍历JSON在golang中显示缺少的键?

时间:2019-04-12 19:30:47

标签: json go

我正在为我的应用程序构建翻译工具。我有2个不同的json文件(en.json,fr.json),其中的键和值都在其中。

en.json文件是引用文件,这意味着存在于此文件中的密钥(如果不存在)需要添加到fr.json文件中。 有关更多详细信息,如果密钥存在于en.json中,而不存在于fr.json中,则需要显示,但如果密钥仅存在于fr.json中,则该密钥不计数,并且我们在屏幕上不显示任何内容。而且,如果两个键中都已经存在该键,则我们不需要在屏幕上显示任何内容。

en.json文件是具有以下键的引用文件:

  {
  "i18n-outterJSON": {
        "i18n-value1": "value1",
        "i18n-value2": "value2",
        "i18n-dad" : "dady"
    },
    "InnerJSON2":"NoneValue",
    "hello" : "good morning",
    "onlykey" : "only key",
    "secondekey" : "second key",
    "mother": {
      "daugther": "fille"
    }

}

fr.json文件是目标文件。使用以下键:

    {
  "i18n-outterJSON": {
    "i18n-value1": "value1",
    "i18n-value2": "value2"
  },
  "i18n-hello" : "bonjour",
  "i18n-variation" : "variation",
  "alouette" : "cacahouete",
  "InnerJSON2":"pas de valeur",
  "hello" : "bonjour"
}

我在golang中的代码是:

fileEnglish := GetAllPathRefFile(); // to open the reference file
  files := GetAllI18nFiles(); // to open the french file

  for _, fileRef := range fileEnglish {
    mapRef := ReadJsonFile(constants.PathRefFile + GetRidOfExtension(fileRef.Name()))

    for _, fileTarget := range files {
      mapTarget := ReadJsonFile(constants.I18nPath + GetRidOfExtension(fileTarget.Name()));
      mapTarget = MissingKey(mapRef, mapTarget)



      // range loop to identify the missing keys in the different files
      for key, _ := range mapRef { // mapRef is the reference map of the reference file en.json
        if  mapRef[key] != mapTarget[key]  { // mapTarget is map of the target file fr.json
          t := strings.Replace(key, key, "", -1)
            _ = t
            fmt.Println("the missing keys are: ", key)
            }
          }
        }
      }

我试图比较每个键,在某些情况下,我们有一个层次结构,并且试图识别出丢失的键。 我需要获得此结果:

i18n-dad
mother
daughter
onlykey
secondekey

但是根据我当前的代码,我遇到了这个错误:comparing uncomparable type map[string]interface {}

我们如何识别并正确在屏幕上打印按键?

1 个答案:

答案 0 :(得分:0)

这是一个使用https://github.com/go-test/deep来显示法语JSON中缺少的内容的快速示例。

package main

import (
    "encoding/json"
    "fmt"
    "strings"

    "github.com/go-test/deep"
)

type Data struct {
    I18NOutterJSON struct {
        I18NValue1 string `json:"i18n-value1"`
        I18NValue2 string `json:"i18n-value2"`
        I18NDad    string `json:"i18n-dad"`
    } `json:"i18n-outterJSON"`
    InnerJSON2 string `json:"InnerJSON2"`
    Hello      string `json:"hello"`
    Onlykey    string `json:"onlykey"`
    Secondekey string `json:"secondekey"`
    Mother     struct {
        Daugther string `json:"daugther"`
    } `json:"mother"`
}

func main() {
    enJSON := []byte(`{"i18n-outterJSON":{"i18n-value1":"value1","i18n-value2":"value2","i18n-dad":"dady"},"InnerJSON2":"NoneValue","hello":"good morning","onlykey":"only key","secondekey":"second key","mother":{"daugther":"fille"}}`)
    frJSON := []byte(`{"i18n-outterJSON":{"i18n-value1":"value1","i18n-value2":"value2"},"i18n-hello":"bonjour","i18n-variation":"variation","alouette":"cacahouete","InnerJSON2":"pas de valeur","hello":"bonjour"}`)

    var en, fr Data
    err := json.Unmarshal(enJSON, &en)
    if err != nil {
        panic(err)
    }

    err = json.Unmarshal(frJSON, &fr)
    if err != nil {
        panic(err)
    }

    diff := deep.Equal(en, fr)
    for _, d := range diff {
        if strings.HasSuffix(d, "!= ") {
            fmt.Printf("%s\n", d)
        }
    }
}

$ go run .
I18NOutterJSON.I18NDad: dady != 
Onlykey: only key != 
Secondekey: second key != 
Mother.Daugther: fille != 

根据评论进行编辑。添加了一种使用任意JSON而不是结构的方法。

func withArbitraryJSON(enJSON []byte, frJSON []byte) {
    var en map[string]interface{}
    err := json.Unmarshal(enJSON, &en)
    if err != nil {
        panic(err)
    }

    var fr map[string]interface{}
    err = json.Unmarshal(frJSON, &fr)
    if err != nil {
        panic(err)
    }

    diff := deep.Equal(en, fr)
    for _, d := range diff {
        if strings.HasSuffix(d, "!= <does not have key>") {
            fmt.Printf("%s\n", d)
        }
    }
}

输出:

$ go run .
map[i18n-outterJSON].map[i18n-dad]: dady != <does not have key>
map[onlykey]: only key != <does not have key>
map[secondekey]: second key != <does not have key>
map[mother]: map[daugther:fille] != <does not have key>