我有一个来自API的JSON响应,如下所示:

{
    "1091500": {
      "data": {
        "price_overview": {
          "final_formatted": "$59.99"
        }
      } 
    }
}

当我解组并访问我需要的价格值时,我拥有的 struct 工作得很好. price.AppID.Data.PriceOverview.FinalFormatted

此处的 struct :

type SteamApp struct {
    AppID struct {
        Data struct {
            PriceOverview struct {
                FinalFormatted string `json:"final_formatted"`
            } `json:"price_overview"`
        } `json:"data"`
    } `json:"1091500"`
}

我正在努力解决的是最高级别的密钥,"1091500".这是一个由单独的函数生成的值,实际上是获取上述数据所需的搜索词.也就是说,它是动态的,并在运行时由单独的API调用发现.因为您需要在 struct 中使用JSON标记,所以我正在努力想出一种泛化它的方法.

到目前为止,最好的方法是找到不同的API,以不同的方式返回数据,但我还没有发现这一点.我还想过找到一种方法来"跳过"最初的部分,因为我有正确的数据,这就是问题所在.提前谢谢你,我希望我的解释已经足够好了.

推荐答案

分两步解组.首先是映射,然后是 struct 类型.您可以通过实现json.Unmarshaler自动完成此操作:

package main

import (
    "encoding/json"
    "fmt"
)

var j = []byte(`{
    "1091500": {
      "data": {
        "price_overview": {
          "final_formatted": "$59.99"
        }
      }
    }
}`)

func main() {
    var t T
    err := json.Unmarshal(j, &t)

    fmt.Println(err)
    fmt.Printf("%+v\n", t)
}

type T struct {
    AppID         string `json:"-"`
    PriceOverview struct {
        FileFormatted string `json:"final_formatted"`
    } `json:"price_overview"`
}

func (t *T) UnmarshalJSON(b []byte) error {
    var m map[string]struct {
        Data json.RawMessage
    }

    err := json.Unmarshal(b, &m)
    if err != nil {
        return err
    }

    type T_ T // prevent recursion
    var t_ T_

    for appID, x := range m {
        err := json.Unmarshal(x.Data, &t_)
        if err != nil {
            return err
        }

        *t = T(t_)
        t.AppID = appID

        break
    }

    return nil
}

在操场上试试:https://go.dev/play/p/NMffrAWEBQy

我假设数据属性只是噪音,并使其透明.如果我弄错了,那么使用map[string] json.RawMessage并将Data字段添加为类型T.

如果您也想自动编组成相同的格式,那么也要实现json.Marshaler:

func (t T) MarshalJSON() ([]byte, error) {
    type T_ T // prevent recursion

    m := map[string]struct {
        Data T_ `json:"data"`
    }{
        t.AppID: {Data: T_(t)},
    }

    return json.Marshal(m)
}

Json相关问答推荐

如何获取brew list作为JSON输出

在Vega中如何通过滑块改变条形图的宽度

如何使用PowerShell从ExchangeOnline命令执行中获得JSON输出

将 REST API - json 输出转换为表 Power BI

在 SQL 存储过程中使用参数 Select 值

XSLT 3.0 Json-to-xml,json 包含 html struct

将 JSON 文件放在哪里以在 Angular 8 应用程序中加载静态 JSON 数据?

在 rust 中从 API 反序列化 serde_json

如何使用 gson 调用默认反序列化

Django - 异常处理最佳实践和发送自定义错误消息

Spring MVC控制器中的JSON参数

将 PHP 结果数组转换为 JSON

消息通知产生此内容无法显示

没有默认构造函数的杰克逊第 3 方类

Spring Security 和 JSON 身份验证

如何访问 JSON 对象数组的第一个元素?

JSON Schema:验证数字或空值

如何使用 Gson 解码具有未知字段的 JSON?

Backbone.js 模型与集合

是否有一个 PHP 函数只在双引号而不是单引号中添加斜杠