如何将 JSON 数组中的所有键都大写?

How do I capitalize all keys in a JSON array?

我正在将 file.json 读入内存。这是一个对象数组,示例:

[
{"id":123123,"language":"ja-JP","location":"Osaka"}
,{"id":33332,"language":"ja-JP","location":"Tokyo"}
,{"id":31231313,"language":"ja-JP","location":"Kobe"}
]

我想操作此 JSON 文件中的某些键,以便它们以大写字母开头。含义

每次找到

"language" 都会变成 "Language"。到目前为止我所做的是制作一个代表每个对象的结构,如下所示:

type sampleStruct struct {
    ID                   int    `json:"id"`
    Language             string `json:"Language"`
    Location             string `json:"Location"`
}

在这里,我定义了大小写。意思是,id 不应该大写,但是 locationlanguage 应该大写。

其余代码如下:

func main() {
    if len(os.Args) < 2 {
        fmt.Println("Missing filename parameter.")
        return
    }

    translationfile, err := ioutil.ReadFile(os.Args[1])
    fileIsValid := isValidJSON(string(translationfile))

    if !fileIsValid {
        fmt.Println("Invalid JSON format for: ", os.Args[1])
        return
    }

    if err != nil {
        fmt.Println("Can't read file: ", os.Args[1])
        panic(err)
    }
}


func isValidJSON(str string) bool {
    var js json.RawMessage
    return json.Unmarshal([]byte(str), &js) == nil
}

// I'm unsure how to iterate through the JSON objects and only uppercase the objects matched in my struct here. 
func upperCaseSpecificKeys()
// ... 

期望的输出,假设结构代表整个数据对象,根据需要转换每个键:

[
{"id":123123,"Language":"ja-JP","Location":"Osaka"}
,{"id":33332,"Language":"ja-JP","Location":"Tokyo"}
,{"id":31231313,"Language":"ja-JP","Location":"Kobe"}
]

一种方法是实现自定义编组方法,虽然不是很灵活:

type upStruct struct {
    ID       int `json:"id"`
    Language string
    Location string
}

type myStruct struct {
    ID       int    `json:"id"`
    Language string `json:"language"`
    Location string `json:"location"`
}

func (m myStruct) MarshalJSON() ([]byte, error) {
    return json.Marshal(upStruct(m))
}
....
func main() {
    var mySArr []myStruct

    // 1. Unmarshal the input
    err := json.Unmarshal([]byte(myJson), &mySArr)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Input: \n%+v\n", mySArr)

    // 2. Then, marshal it using our custom marshal method
    val, err := json.Marshal(mySArr)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Output: \n%v\n", string(val))
}

Link 到工作代码:https://play.golang.org/p/T4twqPc34k0

感谢mkopriva

json.Unmarshal 上的文档说(特别强调):

To unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match

参见此处示例:https://play.golang.org/p/1vv8PaQUOfg