如何在Golang的顶级结构中检索嵌套的json值?

如何在Golang的顶级结构中检索嵌套的json值?,json,go,struct,Json,Go,Struct,我试图从一个API调用中检索数据,并将它们传递给另一个服务。我收到的数据是在一个特定的JSON结构中,我想将其映射到一个结构,但没有多级数据。我尝试了点符号来获取更深的值,但它不起作用 基本上,我试图获得一个包含一系列“问题”(key、self、description)的结构,但没有“fields.description”结构 JSON: { "ticket": { "number": "2", "issu

我试图从一个API调用中检索数据,并将它们传递给另一个服务。我收到的数据是在一个特定的JSON结构中,我想将其映射到一个结构,但没有多级数据。我尝试了点符号来获取更深的值,但它不起作用

基本上,我试图获得一个包含一系列“问题”(key、self、description)的结构,但没有“fields.description”结构

JSON:

{
  "ticket": {
    "number": "2",
    "issues": [
      {
        "key": "TA-2",
        "self": "http://localhost:8080/rest/api/2/issue/10100",
        "fields": {
          "description": "This template is used to create openshift project.\n|Type|Value|Help|\n|project_name|personal_project|Enter the name of your openshift project|\n|memory|8GB|Enter the desired amount of memory|"
        }
      },
      {
        "key": "TA-1",
        "self": "http://localhost:8080/rest/api/2/issue/10000",
        "fields": {
          "description": "This template is used to create openshift project.\n|Type|Value|Help|\n|project_name|my_openshift_project|Enter the name of your openshift project|\n|memory|4GB|Enter the desired amount of memory|"
        }
      }
    ]
  }
}
结构:

type Todo struct {
  Number string `json:"number"`
  Issue  []struct {
      Key         string `json:"key"`
      Self        string `json:"self"`
      Description string `json:"field.description"` //doesn't work. don't know what to put ...
  } `json:"issues"`
}
预期/期望的结构:

{
  "number": "2",
  "issues": [{
    "key": "TA-2",
    "self": "http://localhost:8080/rest/api/2/issue/10100",
    "description": "This template ..."
  }, {
    "key": "TA-1",
    "self": "http://localhost:8080/rest/api/2/issue/10000",
    "description": "This template ..."
  }]
}
可能吗?如果是,怎么做?使用嵌套结构不会更改初始JSON结构


谢谢

您不能在json结构标记中添加点符号。如果您希望在
字段
下有多个字段,并且如果您确定每个字段值都是
字符串
,则可以将JSON解组为

type Todo struct {
  Number string `json:"number"`
  Issue  []struct {
      Key         string `json:"key"`
      Self        string `json:"self"`
      Fields map[string]string `json:"fields"`
  } `json:"issues"`
}
如果每次只显示
说明
,则可以添加

Fields struct {
    Description string `json:"description"`
} `json:"fields"`

您至少有三种选择:

  • 创建一组单独的结构类型,以JSON提供的格式表示数据。这可能包括一个带有
    ticket
    字段的
    TodoList
    结构,它引用一个单独的
    Todo
    结构。此结构可能有一个
    number
    字段和一个
    issues
    字段。每个
    问题
    结构可能有一个
    字段
    字段,该字段又有一个
    描述
    字段。基本上,您可以重新创建JSON中表示的整个域,然后只需调用
    JSON.Unmarshal()
    即可将JSON解组到
    TodoList
    中。一旦您有了一个
    TodoList
    ,只需手动将其转换为所需的表示形式即可
  • Todo
    Issue
    结构编写自己的自定义
    UnmarshalJSON()
    函数。单击此处查看GoLang文档中的示例
  • 在外部函数中手动解组整个JSON文档。这可能涉及将数据解组为
    map[string]json.RawMessage
    ,然后将许多
    json.RawMessage
    对象映射到其他映射和对象,等等
  • 第一个选项更适用于以下情况:您只需要对所需的数据进行替代表示,但所有数据仍在JSON文档中,并且JSON文档中的所有数据仍然相关。这似乎符合你的困境,所以这是我推荐的选择

    第二个选项更适用于您只想认识到结构的JSON编码应该提供与GoLang对象编码一致不同的表示的情况。换句话说,当结构编码为GoLang对象时,它应该采用一种形式,而当结构编码为JSON时,它应该采用另一种形式。这两种形式必须严格地绑定到它们的编码(JSON与GoLang对象)。如果您计划将JSON解组为GoLang对象,然后将其重新编组为与开始时不同的JSON表示形式,这可能不是最好的选择,因为
    JSON.Unmarshal()
    JSON.Marshal()
    应该是相反的。否则,你就违反了最小惊讶原则。此选项还可用于延迟或防止通过
    json.RawMessage
    对象对嵌套属性进行解组。因此,如果您有一些动态类型的JSON字段,其类型是在检查其他字段后确定的,或者如果JSON文档中有大量不相关的数据,则可以延迟或防止对这些数据进行解组,直到需要时为止


    实际上,第三种选择与第二种非常相似。但是,通过提供外部解组机制而不是实现
    UnmarshalJSON()
    ,您不太可能违反最小惊讶原则。也就是说,必须保留
    json.Unmarshal()
    json.Marshal()
    之间的感知契约。因此,您可以按照自己的意愿封送和解封送数据,并且可以按照自己的意愿维护每个编码的不同表示形式。也就是说,第一种选择提供了同样的好处,而且容易得多。实际上,只有在第一个和第二个选项不满足要求的情况下,才应该选择第三个选项,例如,当您可能需要延迟或防止对嵌套属性(如第二个选项)进行解组时,同时提供多个不同的JSON表示并保留
    JSON.Marshal()之间的约定
    json.Unmarshal()
    (与第一个选项类似)。

    感谢您的回复,但这并不能解决我的问题,因为它将生成一个与json具有相同表示形式的结构;我想“简化”JSON结构,同时将其与我的结构相匹配。我在OP中添加了“expected/desired”结构。