再次解析复数 JSON

Parsing complex JSON, again

我有一些通过 API 调用获得的 JSON,现在我想使用 JSON 解析它,我遵循了如何解析 JSON 的在线教程] 使用结构,但我的实际 JSON 比他们使用的要复杂得多。这是我拥有的 JSON 的示例:

{
    "metadata": {},
    "items": [
      {
        "metadata": {
          "name": "run7",
          "namespace": "default",
          "uid": "e218fcc4",
          "creationTimestamp": "2022-01-01T00:00:00Z"
        },
        "spec": {
          "arguments": {}
        },
        "status": {
          "phase": "Succeeded",
          "startedAt": "2022-01-01T00:00:00Z",
          "finishedAt": "2022-01-01T00:00:00Z"
        }
      }
    ]
}

这是我为它创建的结构:

type wfSpec struct{
    Arguments string
}

type wfStatus struct {
    Phase  string
    StartedAt   string
    FinishedAt    string
}

type wfMetadata struct {
    Name string
    Namespace string
    Uid string
    CreationTimestamp string
}

type Metadata []struct {
    Data string
}

type Items []struct {
    wfMetadata
    wfStatus
    wfSpec
}

type Workflow struct {
    Metadata  Metadata
    Items     Items
}

当我第一次尝试使用 fmt.Printf(workflows.Items.wfMetadata.Name) 打印一个值时,我得到了错误 workflows.Items.Metadata undefined (type Items has no field or method Metadata) 所以然后我尝试使用 fmt.Printf(workflows) 打印整个东西,但我得到了这个错误 cannot use workflows (type Workflow) as type string in argument to fmt.Printf

我需要从 JSON 解析的唯一数据是

"name": "run7",
"namespace": "default",
"uid": "e218fcc4",
"creationTimestamp": "2022-01-01T00:00:00Z"

首发

  1. 我预计您遇到的问题是没有使用标签。要解析 JSON,结构的名称必须与 JSON 字段中的名称匹配。阅读此处 Golang Marshal
  2. 其次wfMetadata首字母小写,表示不会被导入
  3. 第三,workflow.metadataworkflow.items[i].spec.arguments设置为{}而不是空字符串""。我假设它们不应该是 string。如果您不知道或不关心,可以使用开放 interface{} 来避免这种情况,或者使用您正在连接的 API 中的官方文档实际实现它们。
  4. 请注意,使用 []struct 对我来说似乎是错误的。而是在 usage
  5. 中定义它

Note, by using an IDE like GoLand from jetbrains they first off support converting JSON to a struct by simply pasting the JSON into a .go file. They might be daunting at first but do help a lot, and would do much of this for you in seconds.

现在试试这个,了解为什么以及如何更好地工作。

type Status struct {
    Phase      string `json:"phase"`
    StartedAt  string `json:"startedAt"`
    FinishedAt string `json:"finishedAt"`
}

type ItemMetadata struct {
    Name              string `json:"name"`
    Namespace         string `json:"namespace"`
    UID               string `json:"uid"`
    CreationTimestamp string `json:"creationTimestamp"`
}

type Items struct {
    Metadata ItemMetadata `json:"metadata"`
    Status   Status       `json:"status"`
    Spec     interface{}  `json:"spec"`
}

type Workflow struct {
    Metadata interface{} `json:"metadata"`
    Items    []Items     `json:"items"`
}

Working example in playground https://go.dev/play/p/d9rT4FZJsGv