小伙伴们对Golang编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《json解析后如何列出未知字段》,就很适合你,本篇文章讲解的知识点主要包括。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!
问题内容假设我们有以下 go 结构:
type config struct {
name string `json:"name,omitempty"`
params []param `json:"params,omitempty"`
}
type param struct {
name string `json:"name,omitempty"`
value string `json:"value,omitempty"`
}
和以下 json:
{
"name": "parabolic",
"subdir": "pb",
"params": [{
"name": "input",
"value": "in.csv"
}, {
"name": "output",
"value": "out.csv",
"tune": "fine"
}]
}
我们进行解组:
cfg := Config{}
if err := json.Unmarshal([]byte(cfgString), &cfg); err != nil {
log.Fatalf("Error unmarshalling json: %v", err)
}
fmt.Println(cfg)
https://play.golang.org/p/hzgo0jxbqrp
输出将为 {parabolic [{input in.csv} {output out.csv}]}
,这是有意义的 - 未知字段被忽略。
问题:如何找出哪些字段被忽略了?
即getignoredfields(cfg, cfgstring)
将返回 ["subdir", "params[1].tune"]
(有一个 disallowunknownfields
选项,但它不同:此选项会导致 unmarshal
错误,而问题是如何仍然解析 json 而没有错误并找出哪些字段被忽略)
解决方案
不确定这是否是最好的方法,但我所做的是:
如果当前级别类型是map:
- 检查所有地图键是否已知。
- 键可能是结构字段名称或映射键。
- 如果未知 - 添加到未知字段列表
- 递归地重复每个键对应的值
- 检查所有地图键是否已知。
如果当前关卡类型为数组:
- 对每个元素递归运行
代码:
// ValidateUnknownFields checks that provided json
// matches provided struct. If that is not the case
// list of unknown fields is returned.
func ValidateUnknownFields(jsn []byte, strct interface{}) ([]string, error) {
var obj interface{}
err := json.Unmarshal(jsn, &obj)
if err != nil {
return nil, fmt.Errorf("error while unmarshaling json: %v", err)
}
return checkUnknownFields("", obj, reflect.ValueOf(strct)), nil
}
func checkUnknownFields(keyPref string, jsn interface{}, strct reflect.Value) []string {
var uf []string
switch concreteVal := jsn.(type) {
case map[string]interface{}:
// Iterate over map and check every value
for field, val := range concreteVal {
fullKey := fmt.Sprintf("%s.%s", keyPref, field)
subStrct := getSubStruct(field, strct)
if !subStrct.IsValid() {
uf = append(uf, fullKey[1:])
} else {
subUf := checkUnknownFields(fullKey, val, subStrct)
uf = append(uf, subUf...)
}
}
case []interface{}:
for i, val := range concreteVal {
fullKey := fmt.Sprintf("%s[%v]", keyPref, i)
subStrct := strct.Index(i)
uf = append(uf, checkUnknownFields(fullKey, val, subStrct)...)
}
}
return uf
}
完整版:https://github.com/yb172/json-unknown/blob/master/validator.go
好了,本文到此结束,带大家了解了《json解析后如何列出未知字段》,希望本文对你有所帮助!关注编程网公众号,给大家分享更多Golang知识!