Unmarshaling Nested JSON Without Structural Knowledge
Problem Statement
When dealing with nested JSON data, it can be challenging to determine the appropriate struct to unmarshal into. This is especially true for data stored in a key-value store, where the structure of the JSON data can vary widely.
Question 1: Avoiding Repeated Unmarshaling
While repeated unmarshaling may incur some performance overhead, it is not necessarily something to avoid unless it becomes a significant bottleneck.
Question 2: Determining the Struct Type
There are two main methods to determine the struct type:
Method 1: Unmarshaling to an Interface
Method 2: Using Regular Expressions
Once the struct type is determined, you can then unmarshal the data:
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) } }
Example Code:
// 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") }
The above is the detailed content of How to Unmarshal Nested JSON Data Without Knowing Its Structure?. For more information, please follow other related articles on the PHP Chinese website!