Home >Backend Development >Golang >How to Dynamically Convert YAML to JSON in Go without Predefined Structs?

How to Dynamically Convert YAML to JSON in Go without Predefined Structs?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-28 14:57:14573browse

How to Dynamically Convert YAML to JSON in Go without Predefined Structs?

Convert YAML to JSON Dynamically without a Defined Struct

You have a dynamic YAML configuration string that you want to convert to JSON. However, you cannot define a struct for the JSON because the data structure is unknown.

To overcome this challenge, you can use the yaml.Unmarshal() function to parse the YAML into an interface{} value. This will produce a nested data structure of maps and slices with the default interface{} type.

The problem arises when you try to convert this interface{} value back to JSON using json.Marshal(). It will fail because json.Marshal() does not support the map[interface{}]interface{} type.

To handle this dynamic data structure, you need to recursively convert the map[interface{}]interface{} values to map[string]interface{} values. This ensures that all maps have string keys, which are supported by JSON.

Here's an example converter function:

func convert(i interface{}) interface{} {
    switch x := i.(type) {
    case map[interface{}]interface{}:
        m2 := map[string]interface{}{}
        for k, v := range x {
            m2[k.(string)] = convert(v)
        }
        return m2
    case []interface{}:
        for i, v := range x {
            x[i] = convert(v)
        }
    }
    return i
}

Using this function, you can convert the interface{} value to a JSON-compatible data structure:

body = convert(body)

Now, you can use json.Marshal() to convert the converted body to a JSON string.

Here's a complete example:

func main() {
    const s = `Services:
-   Orders:
    -   ID: $save ID1
        SupplierOrderCode: $SupplierOrderCode
    -   ID: $save ID2
        SupplierOrderCode: 111111
`
    var body interface{}
    if err := yaml.Unmarshal([]byte(s), &body); err != nil {
        panic(err)
    }

    body = convert(body)

    if b, err := json.Marshal(body); err != nil {
        panic(err)
    } else {
        fmt.Printf("Output: %s\n", b)
    }
}

Output:

Output: {"Services":[{"Orders":[{"ID":"$save ID1","SupplierOrderCode":"$SupplierOrderCode"},{"ID":"$save ID2","SupplierOrderCode":111111}]}]}

Note that the order of elements in the JSON output may differ from the original YAML due to the unordered nature of Go maps.

The above is the detailed content of How to Dynamically Convert YAML to JSON in Go without Predefined Structs?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn