一貫性のない JSON フィールドの処理: 文字列または配列としてのアンマーシャリング
矛盾を示す JSON データを扱う場合、アンマーシャリングが困難になる場合があります文字列または文字列の配列など、型が異なるフィールド。この記事では、この問題に対処し、実用的な解決策を示します。
問題
「display_name」フィールドが文字列または文字列の配列である次の JSON 構造を考えてみましょう。 :
{ "date": "30 Apr", "display_name": "Mr Smith" }, { "date": "30 Apr", "display_name": ["Mr Smith", "Mr Jones"], }
次の Go 構造を使用してこのデータをアンマーシャルしようとすると、 error:
type MyListItem struct { Date string `json:"date"` DisplayName string `json:"display_name"` } type MyListings struct { CLItems []MyListItem `json:"myitems"` }
解決策
この課題を克服するには、さまざまなフィールド データのキャプチャを可能にする json.RawMessage の多用途性を利用できます。さらに、「-」フィールド名を使用してデコーダから「DisplayName」フィールドを非表示にし、最上位の JSON がデコードされた後にアプリケーションがフィールドに値を設定できるようにします。
変更された Go 構造
type MyListItem struct { Date string `json:"date"` RawDisplayName json.RawMessage `json:"display_name"` DisplayName []string `json:"-"` }
アンマーシャリングプロセス
トップレベル JSON のアンマーシャリング:
var li MyListItem if err := json.Unmarshal(data, &li); err != nil { // handle error }
生データのタイプに基づいて "display_name" フィールドを再構築:
if len(li.RawDisplayName) > 0 { switch li.RawDisplayName[0] { case '"': if err := json.Unmarshal(li.RawDisplayName, &li.DisplayName); err != nil { // handle error } case '[': var s []string if err := json.Unmarshal(li.RawDisplayName, &s); err != nil { // handle error } // Join arrays with "&&" per OP's comment on the question. li.DisplayName = strings.Join(s, "&&") } }
Forデータ モデル内でこの一貫性のないフィールドが複数回発生すること、json.Unmarshaler インターフェイスのカスタム タイプと実装ロジックをカプセル化するために使用できます。
カスタム アンマーシャラー
type multiString string func (ms *multiString) UnmarshalJSON(data []byte) error { if len(data) > 0 { switch data[0] { case '"': var s string if err := json.Unmarshal(data, &s); err != nil { return err } *ms = multiString(s) case '[': var s []string if err := json.Unmarshal(data, &s); err != nil { return err } *ms = multiString(strings.Join(s, "&&")) } } return nil }
カスタム アンマーシャラーとの使用
type MyListItem struct { Date string `json:"date"` DisplayName multiString `json:"display_name"` } type MyListings struct { CLItems []MyListItem `json:"myitems"` } var listings MyListings if err := json.Unmarshal([]byte(data), &listings); err != nil { log.Fatal(err) }
これらのソリューションは、一貫性のない JSON フィールドを効率的に処理するための包括的なアプローチを提供し、柔軟なマッピングを可能にします。データ構造と JSON 表現の間。
以上がGo で文字列である場合もあれば文字列の配列である場合もある、一貫性のない JSON フィールドを効率的にアンマーシャリングするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。