我想看看是否以.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