I'm trying to see if a .json file has multiple of the same keys
"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
Any help would be grateful thank you!
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.
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.
You can create a json.Unmarshaler
string type that returns an error if it is assigned more than once while unmarshaling.
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:
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
}