構造知識なしでネストされた JSON をアンマーシャリングする
問題ステートメント
ネストされた JSON データを扱う場合、アンマーシャルする適切な構造体を決定するのは困難な場合があります。これは、JSON データの構造が大きく異なる可能性がある Key-Value ストアに保存されたデータに特に当てはまります。
質問 1: 繰り返しのアンマーシャリングを回避する
アンマーシャリングを繰り返すとパフォーマンスのオーバーヘッドが発生する可能性がありますが、重大なボトルネックにならない限り、必ずしも回避する必要はありません。
質問 2: 構造体の型の決定
次の 2 つがあります。構造体のタイプを決定する主なメソッド:
方法 1: インターフェースへのアンマーシャリング
方法 2: 正規表現を使用する
構造体の型が決定したら、構造体の型をアンマーシャリングできます。データ:
varbazorbar interface{} if err := json.Unmarshal(*objmap["foo"], &bazorbar); err !=nil{ return err } switch v := bazorbar.(type) { case map[string]*json.RawMessage: // If the data is a nested JSON object, further unmarshaling is needed. result, err := unmarshalNested(v["nested_data"]) if err != nil return err foo.Nested_Data = result case []interface{}: // If the data is an array of JSON objects, process each element. for _, item := range v { result, err := unmarshalNested(item.(map[string]interface{})) if err != nil return err foo.Nested_Array = append(foo.Nested_Array, result) } }
コード例:
// Unmarshals nested JSON data. func unmarshalNested(data map[string]interface{}) (interface{}, error) { type_expr := regexp.MustCompile(`"type":\s*"([a-zA-Z]+)"`) matches := type_expr.FindStringSubmatch(data["foo"].(string)) if len(matches) == 2 { switch matches[1] { case "Baz": var baz Baz if err := json.Unmarshal([]byte(data["foo"].(string)), &baz); err != nil { return nil, err } return baz, nil case "Bar": var bar Bar if err := json.Unmarshal([]byte(data["foo"].(string)), &bar); err != nil { return nil, err } return bar, nil } } return nil, errors.New("cannot determine type") }
以上が構造を知らずにネストされた JSON データをアンマーシャリングする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。