Arrays golang json非结构化数据

Arrays golang json非结构化数据,arrays,json,go,Arrays,Json,Go,我有一个json(非结构化),希望从json数据中检索每个键 然后循环遍历键和值。如果值的类型为json(嵌套)或array,则继续 我已经找到了一个结构化json解析的示例,但无法得到它。 已检查此代码,但无法获取完整的代码 err := json.Unmarshal([]byte(input), &customers) 示例json: { “组成部分”:[ { “密钥”:“d1”, “组成部分”:[ { “密钥”:“客户名称”, “价值”:“亚伯拉罕”, “输入”:正确, “tab

我有一个json(非结构化),希望从json数据中检索每个键 然后循环遍历键和值。如果值的类型为json(嵌套)或array,则继续

我已经找到了一个结构化json解析的示例,但无法得到它。 已检查此代码,但无法获取完整的代码

err := json.Unmarshal([]byte(input), &customers)
示例json:

{
“组成部分”:[
{
“密钥”:“d1”,
“组成部分”:[
{
“密钥”:“客户名称”,
“价值”:“亚伯拉罕”,
“输入”:正确,
“tableView”:正确
},
{
“键”:“类型”,
“类型”:“收音机”,
“标签”:“First”,
“价值观”:[
{
“标签”:“鞋底”,
“价值”:“唯一”,
“快捷方式”:”
},
{
“标签”:“Bata”,
“价值”:“Bata”,
“快捷方式”:”
}
],
“验证”:{
“必需”:true
},
“tableView”:错误
},
{
“密钥”:“registeredField”,
“值”:“reg 111”,
“输入”:正确,
},
{
“密钥”:“dirc”,
“价值”:“亚伯拉罕”,
},
{
“密钥”:“gst”,
“值”:“文本字段”,
“useLocaleSettings”:false
},
{
“键”:“pan”,
“价值”:“AAAAA 0000”,
“useLocaleSettings”:false
}
],
“可折叠”:错误
}
]
}
预期产出:

Key: custname Value: Abraham
Key: type Value: {
    "label": "Sole",
    "value": "sole",
    "shortcut": ""
}, {
    "label": "Bata",
    "value": "Bata",
    "shortcut": ""
}
Key: registeredField Value: reg 111

因此,您有一个带有键
components
的对象,这是一个组件切片。每个组件都可以有多个键。首先要做的是评估组件可以拥有的所有可能字段,并使用所述字段定义类型:

type Validation struct {
    Required bool `json:"required"`
}

type Value struct {
    Label    string `json:"label"`
    Value    string `json:"value"`
    Shortcut string `json:"shortcut"`
}

type Data struct {
    Components        []Data      `json:"components,omitempty"`
    Collapsable       bool        `json:"collapsable"`
    Input             bool        `json:"input"`
    Key               string      `json:"key"`
    TableView         bool        `json:"tableView"`
    Type              string      `json:"type"`
    Value             string      `json:"value"`
    UseLocaleSettings bool        `json:"useLocaleSettings"`
    Values            []Value     `json:"values,omitempty"`
    Validate          *Validation `json:"validate,omitempty"`
}
现在,您只需获取输入并将其解组到
数据中
类型:

data := Data{}
if err := json.Unmarshal([]byte(input), &data); err != nil {
    // handle error
    fmt.Printf("Oops, something went wrong: %+v", err)
    return
}
在这一点上,我们有一个结构中的所有数据,所以我们可以开始打印出来。我们注意到的第一件事是
数据
如何基本上包含
数据
类型的一部分。使用递归函数将其全部打印出来是有意义的:

func PrintComponents(data []Data) {
    for _, c := range data {
        if len(c.Components) > 0 {
            PrintComponents(c.Components) // recursive
            continue                      // skip value of this component, remove this line if needed
        }
        val := c.Value // assign string value
        if len(c.Values) > 0 {
            // this component has a slice of values, not a single value
            vals, err := json.MarshalIndent(c.Values, "", "    ") // marshal with indent of 4 spaces, no prefix
            if err != nil {
                fmt.Printf("Oops, looks like we couldn't format something: %+v\n", err)
                return // handle this
            }
            val = string(vals) // marshalled values as string
        }
        fmt.Printf("Key: %s Value: %s\n", c.Key, val) // print output
    }
}
您可以稍微更改此函数,以便为每个递归级别传入一个缩进参数,以便可以在缩进块中打印出组件:

func PrintComponents(data []Data, indent string) {
    for _, c := range data {
        if len(c.Components) > 0 {
            // print the key for this block of components
            fmt.Printf("Component block: %s\n", c.Key)
            PrintComponents(data, indent + "    ") // current indent + 4 spaces
            continue // we're done with this component
        }
        val := c.Value
        if len(c.Values) > 0 {
            vals, _ := json.MarshalIndent(c.Values, indent, "    ") // pass in indent level here, and DON'T ignore the error, that's just for brevity
            val = string(vals)
        }
        fmt.Printf("%sKey: %s Value: %s\n", indent, c.Key, val) // pass in indent
    }
}
综上所述,我们得到:

哪些产出:

Printing with simple recursive function
Key: custname Value: Abraham
Key: type Value: [
    {
        "label": "Sole",
        "value": "sole",
        "shortcut": ""
    },
    {
        "label": "Bata",
        "value": "Bata",
        "shortcut": ""
    }
]
Key: registeredField Value: reg 111
Key: dirc Value: abraham
Key: gst Value: textfield
Key: pan Value: AAAAA0000


Printing with indented recursion:
Component block: d1
    Key: custname Value: Abraham
    Key: type Value: [
        {
            "label": "Sole",
            "value": "sole",
            "shortcut": ""
        },
        {
            "label": "Bata",
            "value": "Bata",
            "shortcut": ""
        }
    ]
    Key: registeredField Value: reg 111
    Key: dirc Value: abraham
    Key: gst Value: textfield
    Key: pan Value: AAAAA0000
所需的输出不包括值切片的方括号。嗯,这是一件很容易摆脱的事情。方括号始终是字符串的第一个和最后一个字符,
json.Marshal
返回一个字节片(
[]字节
)。切掉第一个和最后一个字符非常简单:

val = string(vals[1:len(vals)-2])
获取由
json.marshall
返回的字节片的一个子片,从偏移量1开始(剪切偏移量0,即
[/code>),并将所有内容保留到最后一个字符(偏移量
len(vals)-2
)。对于缩进示例,这将留下一条空行,其中包含未知数量的空格(缩进)。您可以使用
strings
包修剪字符串的右侧:

// remove square brackets, trim trailing new-line and spaces
val = strings.TrimRight(string(vals[1:len(vals)-2]), "\n ")

编辑问题以显示变量
客户的类型
、您尝试的代码和遇到的问题……并请包括“非结构化json”的示例……以及“非结构化json”的预期结果。Go中JSON解组的每个方面都已经得到了回答。预期的输出不是JSON或Go值。不清楚您要求的是什么。
// remove square brackets, trim trailing new-line and spaces
val = strings.TrimRight(string(vals[1:len(vals)-2]), "\n ")