问题描述
在Go中,如何将JSON中的snake_case密钥递归转换为camelCase密钥?
In Go, how can we convert snake_case keys in a JSON to camelCase ones recursively?
我正在Go中编写一个http api.该API从数据存储区中获取数据,进行一些计算,然后以JSON格式返回响应.
I am writing one http api in Go. This api fetches data from datastore, does some computation and return the response as JSON.
情况是,数据存储区(elasticsearch)中的JSON文档带有snake_case键,而API响应应基于camelCase(这只是为了与项目中的其他api标准保持一致).插入ES的源无法修改.因此,它仅在api级别进行键转换.
Situation is that the JSON document in the datastore (elasticsearch) is present with snake_case keys while the API response should be camelCase based (this is just to align with other api standard within project). The source which inserts into ES can't be modified. So its only at the api level keys conversion has to take place.
我编写了一个结构,可以很好地从数据存储中读取JSON.但是如何在Go中将密钥转换为camlelCase?
I have written a struct which is reading JSON from datastore nicely. But how can I convert the keys to camlelCase in Go?
可以嵌套JSON,并且必须转换所有键.JSON任意大.即一些键只是映射到类型interface {}
The JSON is can be nested and all keys has to be converted.The JSON is arbitrarily large. i.e. some keys are just mapped to type interface{}
我也正在使用go的echo框架来编写api.
I am also using go's echo framework for writing the api.
例如.
{
"is_modified" : true,
{ attribute":
{
"legacy_id" : 12345
}
}
}
TO
{
"isModified" : true,
{ attribute":
{
"legacyId" : 12345
}
}
}
任何有关如何在Go中执行此操作的指针吗?
Any pointers on how to do this in Go?
结构:
type data_in_es struct {
IsModified bool `json:"is_modified,omitempty"`
Attribute *attribute `json:"attribute,omitempty"`
}
type attribute struct {
LegacyId int `json:"legacy_id,omitempty"`
}
推荐答案
从Go 1.8开始,您可以定义两个结构,它们的标签仅不同,并在两者之间轻松转换:
Since Go 1.8 you can define two structs that only differ in their tags and trivially convert between the two:
package main
import (
"encoding/json"
"fmt"
)
type ESModel struct {
AB string `json:"a_b"`
}
type APIModel struct {
AB string `json:"aB"`
}
func main() {
b := []byte(`{
"a_b": "c"
}`)
var x ESModel
json.Unmarshal(b, &x)
b, _ = json.MarshalIndent(APIModel(x), "", " ")
fmt.Println(string(b))
}
https://play.golang.org/p/dcBkkX9zQR
通常要执行此操作,请尝试将JSON文档解组到地图中.如果成功,请修复所有键并针对映射中的每个值递归调用您的函数.下面的示例显示如何将所有键转换为大写字母.将 fixKey
替换为snake_case转换函数.
To do this in general, attempt to unmarshal the JSON document into a map. If it succeeds, fix all the keys and recursively call your function for each value in the map. The example below shows how to convert all keys to upper case. Replace fixKey
with the snake_case conversion function.
package main
import (
"bytes"
"encoding/json"
"fmt"
"strings"
)
func main() {
// Document source as returned by Elasticsearch
b := json.RawMessage(`{
"a_b": "c",
"d_e": ["d"],
"e_f": {
"g_h": {
"i_j": "k",
"l_m": {}
}
}
}`)
x := convertKeys(b)
buf := &bytes.Buffer{}
json.Indent(buf, []byte(x), "", " ")
fmt.Println(buf.String())
}
func convertKeys(j json.RawMessage) json.RawMessage {
m := make(map[string]json.RawMessage)
if err := json.Unmarshal([]byte(j), &m); err != nil {
// Not a JSON object
return j
}
for k, v := range m {
fixed := fixKey(k)
delete(m, k)
m[fixed] = convertKeys(v)
}
b, err := json.Marshal(m)
if err != nil {
return j
}
return json.RawMessage(b)
}
func fixKey(key string) string {
return strings.ToUpper(key)
}
https://play.golang.org/p/QQZPMGKrlg
这篇关于将json中的所有snake_case密钥转换为camelCase密钥的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!