Как распарсить json с меняющейся структурой?

Распарсить JSON с меняющейся структурой может быть сложной задачей, но с использованием некоторых стратегий можно справиться с ней.

1. Использование интерфейса: В языке программирования Go можно использовать интерфейсы для динамического обработки меняющейся структуры JSON. Создайте интерфейс, который определяет все возможные поля JSON, и затем последовательно проверяйте наличие этих полей в разобранном JSON. Например, если есть поле "name", вы можете использовать приведение типов для получения значения этого поля, даже если оно отсутствует в остальных структурах JSON.

type JSONStruct struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    // ...
}

func main() {
    // JSON input
    input := []byte(`{"name":"John","age":30}`)

    // Create a variable of the interface type
    var jsonData interface{}

    // Unmarshal the JSON into the interface
    err := json.Unmarshal(input, &jsonData)
    if err != nil {
        log.Fatal(err)
    }

    // Check if the "name" field exists in the JSON
    if value, ok := jsonData.(map[string]interface{})["name"]; ok {
        // the "name" field exists, do something with the value
        name := value.(string)
        fmt.Println("Name:", name)
    } else {
        fmt.Println("Name field does not exist in the JSON")
    }

    // Check if the "age" field exists in the JSON
    if value, ok := jsonData.(map[string]interface{})["age"]; ok {
        // the "age" field exists, do something with the value
        age := int(value.(float64))
        fmt.Println("Age:", age)
    } else {
        fmt.Println("Age field does not exist in the JSON")
    }
}

2. Использование рекурсии: Если структура JSON имеет вложенные объекты или массивы с меняющимися структурами, может быть полезно использовать рекурсию для обработки всех возможных путей в JSON. В этом случае вам придется рекурсивно вызывать функцию обработки для каждого объекта или массива внутри JSON.

type JSONStruct struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
    // ...
}

func processJSON(data interface{}) {
    switch v := data.(type) {
    case map[string]interface{}:
        for key, value := range v {
            switch key {
            case "name":
                name := value.(string)
                fmt.Println("Name:", name)
            case "age":
                age := int(value.(float64))
                fmt.Println("Age:", age)
            }
        }
    case []interface{}:
        for _, item := range v {
            processJSON(item)
        }
    }
}

func main() {
    // JSON input
    input := []byte(`{"data":[{"name":"John","age":30},{"name":"Jane","age":25}]}`)

    // Create a variable of the interface type
    var jsonData interface{}

    // Unmarshal the JSON into the interface
    err := json.Unmarshal(input, &jsonData)
    if err != nil {
        log.Fatal(err)
    }

    // Process the JSON
    processJSON(jsonData)
}

Это только два примера того, как можно распарсить JSON с меняющейся структурой в Go. В вашем конкретном случае может потребоваться изменить код, чтобы учесть все возможные варианты возможной структуры JSON. Также помните, что при парсинге JSON может возникнуть неожиданные ошибки, поэтому всегда заботьтесь о проверке ошибок и валидации данных.