2016-07-28 11 views
4

の倍数を持っているかどうかを確認しているかどうかを確認するために、外出先での方法がありますjsonのキー'name'が複数回使用されていますか? 同じ名前の複数のキーを持つJSONファイルをアンマーシャル場合には行く、あなたに感謝すべてのヘルプは感謝されることは以前に書かれたキーを書き換えますとgauge1.namesomeName1アンマーシャリングでJSONオブジェクトは、私が.jsonファイルが同じキー</p> <pre><code>"gauge1":{ "name":"someName", "name":"someName1" } </code></pre> <p>の倍数を持っているかどうかを確認しようとしている同じキー

になります!

答えて

1

は恐らくあなたがencoding/jsonパッケージ—の低レベルのデコード機能を使用する必要があり、すなわち、それは、そのメソッドの入力JSONストリーム内のすべてのトークンを超えるToken()反復するDecoderタイプです。

パースされた値を保持するステートマシンとマップ(またはマップの階層)を組み合わせることで、この方法では、解析中のJSONオブジェクトに同じ名前の兄弟フィールドが既に表示されていたかどうかを確認できます。

3

文字列型を作成して、非マーシャリング中に複数回割り当てられている場合はエラーを返すことができます。 json.Decoderでこれを処理する

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

適切にすべてのフィールドを取得し、優れたエラーメッセージを返すための唯一の方法におそらくあります。これは、外部型の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 
} 
+0

最初のアプローチとの深刻な問題はunmarshalerは、それが中にエラーを検出し、コンテキストのないアイデアを持っていないということであるあなたは、エラーメッセージにフィールドの名前を焼いたが、あなたが必要とする必要があります。たとえば、オブジェクトのすべてのフィールドをチェックすることは実用的ではありません(各フィールドの値のカスタムタイプを定義することができません)。だから、私は2番目の投票に投票します。間違いなく複雑ですが、エラーが検出されると、その値ではなく、問題のキーですぐに検出されます。 – kostix

+0

@kostix:私は同意します。外側のstruct構造体に独自の 'UnmarshlJSON'を実装し、そこで非整列化を行い、' UnmarshalFieldError'や他のより有益なメッセージを返すことで、これを軽減できます。しかし、はい、私は唯一の "適切な"方法は、各トークンの復号化を個別に処理することだと思います。 – JimB

関連する問題

 関連する問題