我想看看是否以.json文件具有相同的键解编时,检查JSON对象具有相同的密钥
"gauge1":{
"name":"someName",
"name":"someName1"
}
多的倍数是有没有去的方式来检查,如果json中的密钥'name'
被多次使用? 在去,如果你解组具有相同名称的多个按键的JSON文件,这将改写先前写入密钥和gauge1.name
将成为someName1
任何帮助将不胜感激,谢谢!
我想看看是否以.json文件具有相同的键解编时,检查JSON对象具有相同的密钥
"gauge1":{
"name":"someName",
"name":"someName1"
}
多的倍数是有没有去的方式来检查,如果json中的密钥'name'
被多次使用? 在去,如果你解组具有相同名称的多个按键的JSON文件,这将改写先前写入密钥和gauge1.name
将成为someName1
任何帮助将不胜感激,谢谢!
按说你应该使用encoding/json
包—的低级别的解码设备,即它的Decoder
类型,其方法Token()
遍历输入JSON流中的所有令牌。
结合状态机和地图(或地图层次结构)来保留解析出来的值,这种方法将允许您检查是否在正在解析的JSON对象中看到同名的兄弟字段。
您可以创建一个json.Unmarshaler
字符串类型,如果它在解组时被分配了多次,则会返回一个错误。
type singleAssignString string
func (s *singleAssignString) UnmarshalJSON(b []byte) error {
if s != nil && *s != "" {
return fmt.Errorf("multiple string assignment")
}
*s = singleAssignString(string(b))
return nil
}
https://play.golang.org/p/v4L1EjTESX
与json.Decoder
处理这可能是唯一的正确获取所有字段,并返回一个良好的错误信息的方式。您可以使用外部类型的UnmarshalJSON方法中的嵌入式解码器执行此操作。一个粗略的例子可能是这样的:
type Data struct {
Name string
}
func (d *Data) UnmarshalJSON(b []byte) error {
dec := json.NewDecoder(bytes.NewReader(b))
key := ""
value := ""
for dec.More() {
tok, err := dec.Token()
if err != nil {
return err
}
s, ok := tok.(string)
if !ok {
continue
}
switch {
case key == "":
key = s
continue
case value == "":
value = s
}
if key == "Name" {
if d.Name != "" {
return fmt.Errorf("multiple assignment to Name")
}
d.Name = s
}
key = ""
}
return nil
}
与第一种方法的一个严重问题是,unmarshaler没有它检测到您出炉字段的名称到错误信息错误的情况下的想法,但你应该需要。检查对象的所有字段,这将是不切实际的(缺少为每个字段的值定义自定义类型)。所以我会为第二个投票:虽然肯定更复杂,但当检测到错误时,它会在违规密钥中检测到,而不是其值。 – kostix
@kostix:我同意。您可以通过使外部结构体结构实现自己的'UnmarshlJSON'来解决这个问题,在那里解组并返回一个'UnmarshalFieldError'或另一个更多的信息性消息。但是,是的,我认为唯一的“正确”方法是单独处理每个令牌的解码。 – JimB