I'm trying to see if a .json file has multiple of the same keys
我正在尝试查看.json文件是否具有多个相同的密钥
"gauge1":{
"name":"someName",
"name":"someName1"
}
is there a way in go to check if the key 'name'
in the json is used more than once? In go if you unmarshal the json file with multiple keys of the same name, it will rewrite the previously written key and gauge1.name
will become someName1
有没有办法检查json中的键'name'是否被多次使用?如果您使用同名的多个键解组json文件,它将重写以前写入的键,而gauge1.name将成为someName1
Any help would be grateful thank you!
任何帮助将不胜感激,谢谢!
2 个解决方案
#1
3
You can create a json.Unmarshaler
string type that returns an error if it is assigned more than once while unmarshaling.
您可以创建一个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
Handling this with the json.Decoder
is probably to only way to properly get all the fields and return a good error message. You can do this with an embedded decoder inside the outer type's UnmarshalJSON method. A rough example might look like:
使用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
}
#2
1
Supposedly you should use low-level decoding facilities of the encoding/json
package—namely, it's Decoder
type whose method Token()
iterates over all the tokens in the input JSON stream.
据说你应该使用encoding / json包的低级解码工具 - 即它的Decoder类型,其方法Token()迭代输入JSON流中的所有标记。
Combined with a state machine and a map (or a hierarchy of maps) to keep parsed out values, this approach will allow you to check whether a sibling field with the same name already was seen in the JSON object being parsed.
结合状态机和映射(或映射层次结构)来保存已解析的值,此方法将允许您检查是否已在要解析的JSON对象中看到具有相同名称的兄弟字段。
#1
3
You can create a json.Unmarshaler
string type that returns an error if it is assigned more than once while unmarshaling.
您可以创建一个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
Handling this with the json.Decoder
is probably to only way to properly get all the fields and return a good error message. You can do this with an embedded decoder inside the outer type's UnmarshalJSON method. A rough example might look like:
使用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
}
#2
1
Supposedly you should use low-level decoding facilities of the encoding/json
package—namely, it's Decoder
type whose method Token()
iterates over all the tokens in the input JSON stream.
据说你应该使用encoding / json包的低级解码工具 - 即它的Decoder类型,其方法Token()迭代输入JSON流中的所有标记。
Combined with a state machine and a map (or a hierarchy of maps) to keep parsed out values, this approach will allow you to check whether a sibling field with the same name already was seen in the JSON object being parsed.
结合状态机和映射(或映射层次结构)来保存已解析的值,此方法将允许您检查是否已在要解析的JSON对象中看到具有相同名称的兄弟字段。