当前位置: 首页 > 知识库问答 >
问题:

将json字符串解组到具有结构本身一个元素的结构

通远
2023-03-14

我是go初学者,正在尝试解组下面的json字符串

[{
    "db": {
        "url": "mongodb://localhost",
        "port": "27000",
        "uname": "",
        "pass": "",
        "authdb": "",
        "replicas": [
            {
                "rs01": {
                    "url":"mongodb://localhost",
                    "port": "27001",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            },
            {
                "rs02": {
                    "url":"mongodb://localhost",
                    "port": "27002",
                    "uname": "",
                    "pass": "",
                    "authdb": ""
                }
            }
        ]
    }
}]

下面是这个结构

type DBS struct {
    URL      string `json:url`
    Port     string `json:port`
    Uname    string `json:uname`
    Pass     string `json:pass`
    Authdb   string `json:authdb`
    Replicas []DBS   `json:replicas`
}

这是函数

func loadConfigs() []DBS {
    var config []DBS
    raw, err := ioutil.ReadFile("./config.json")
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }

    json.Unmarshal(raw, &config)
    return config
}

函数正在返回

{     []}

共有2个答案

岳浩
2023-03-14

如果由于某种原因,您无法使用已经存在的DBS结构,您还可以编写自己的json. Unmarshaler实现。

(在下面的示例中,我确实稍微更改了结构以跟踪名称/键,但这是可选的,没有必要使解组工作。)

type DBS struct {
    name     string

    URL      string `json:url`
    Port     string `json:port`
    Uname    string `json:uname`
    Pass     string `json:pass`
    Authdb   string `json:authdb`
    Replicas []DBS  `json:replicas`
}

func (db *DBS) UnmarshalJSON(data []byte) error {
    raw := map[string]json.RawMessage{}
    if err := json.Unmarshal(data, &raw); err != nil {
        return err
    }
    if len(raw) > 1 {
        return fmt.Errorf("fail")
    }

    type _DBS DBS
    _db := (*_DBS)(db)
    for name, v := range raw {
        db.name = name
        return json.Unmarshal(v, _db)
    }
    return nil
}

https://play.golang.org/p/c288n7holS

曾飞雨
2023-03-14

您的JSON输入不是DBS的切片,因为还有另一个JSON对象包装器,并且DBS的值属于属性"db"

更深入地说,“replicaps”是一个JSON数组,对象持有不同的键,它们的值可以用DBS表示。

因此,要完全描述您的JSON,您需要某种“动态”类型。例如,map就是这样一种动态类型。

因此,您的原始 JSON 输入可以使用以下类型完全建模:[]map[string]DBS。它是一片地图,因为您的 JSON 输入包含一个 JSON 数组。映射键可以对任何属性名称进行建模,并且该值是由 DBS 结构建模的 JSON 对象。

请参阅这个完全解析JSON输入的示例:

type DBS struct {
    URL      string           `json:"url"`
    Port     string           `json:"port"`
    Uname    string           `json:"uname"`
    Pass     string           `json:"pass"`
    Authdb   string           `json:"authdb"`
    Replicas []map[string]DBS `json:"replicas"`
}

func main() {
    var dbs []map[string]DBS
    if err := json.Unmarshal([]byte(src), &dbs); err != nil {
        panic(err)
    }
    fmt.Printf("%+v", dbs)
}

注意正确的标签语法(例如json:"url")。

输出(在围棋操场上尝试):

[map[db:{URL:mongodb://localhost端口: 27000 Uname: Pass: Authdb: Replicas:[map[rs01:{URL:mongodb://localhost端口: 27001 Uname: Pass: Authdb: Replicas:[]}]map[rs02:{URL:mongodb://localhost端口: 27002 Uname: Pass: Authdb: Replicas:[]}]]}]]

请注意,您可以进一步对第一级进行建模,该级别始终为“db”,我们可以切换到指针(我在第一个示例中使用了非指针,因此打印的结果是可读的):

type DBReplicated struct {
    DB *DBS `json:"db"`
}

type DBS struct {
    URL      string            `json:"url"`
    Port     string            `json:"port"`
    Uname    string            `json:"uname"`
    Pass     string            `json:"pass"`
    Authdb   string            `json:"authdb"`
    Replicas []map[string]*DBS `json:"replicas"`
}

func main() {
    var dbs []*DBReplicated
    if err := json.Unmarshal([]byte(src), &dbs); err != nil {
        panic(err)
    }

    db := dbs[0].DB
    fmt.Printf("%+v\n", db)
    for _, dbs := range db.Replicas {
        for name, replica := range dbs {
            fmt.Printf("%s: %+v\n", name, replica)
        }
    }
}

输出(在Go Playground上尝试):

&{URL:mongodb://localhost Port:27000 Uname: Pass: Authdb: Replicas:[map[rs01:0x10538200] map[rs02:0x10538240]]}
rs01: &{URL:mongodb://localhost Port:27001 Uname: Pass: Authdb: Replicas:[]}
rs02: &{URL:mongodb://localhost Port:27002 Uname: Pass: Authdb: Replicas:[]}

 类似资料:
  • 问题内容: 我是初学者,尝试解组以下json字符串 这是结构 这是功能 该函数正在返回 问题答案: 您的JSON输入不是的一部分,因为还有另一个JSON对象包装器,并且值属于属性。 更深入地讲,是一个JSON数组,其中的对象持有不同的键,其值可由表示。 因此,要完全描述您的JSON,您需要某种“动态”类型。例如,地图就是这种动态类型。 因此,您的原始JSON输入可以使用类型完全建模。这是一张地图,

  • 问题内容: 我有字符串: 某种数据可能是字符串: 我如何将其全部转换为上述数组? ) 谢谢帮忙,PK 问题答案: 给定值 这里有一些我可以满足您需要的代码¹: ¹实际上,它的作用还不止于此:它可以简单地封装在一个函数中,并且可以在所有三个输入值上进行配置(您可以将一个具有现有值的数组传递给它,并在必要时对其进行扩展)。

  • 问题内容: 我有两个具有以下结构的json文件 和 如您所见,json和演员表的内部结构相同。我想将这些json文件解编为相同的golang结构。但是我不能为相同的struct元素提供两个名称标签(广播和电影)。我想要类似的东西 在这种情况下,Detail可以同时解析演员和电影。 这是我当前的代码 但它仅适用于第一个标签“ cast”,并在json包含电影的情况下给出nill。 提前致谢。 问题答

  • 问题内容: 假设以下xml元素具有属性和浮点值: 为了解组它,我应该如何定义我的结构? XMLName属性的用法使我感到困惑。什么时候应该将其放置在结构中,何时将其作为标签包装? 问题答案: 在下面,您可以找到解组给定数据的代码。 在删除空格之前,无法正确解组浮点值。 可以使用“,chardata”注释引用标记的内容。 您无需在结构中指定字段,只要它不模糊应使用哪种结构即可。

  • 我关注了 json 根据给出的答案,我尝试了以下 我得到一个空数组,有如下错误。有什么建议吗? json:无法将数组解组为map[string]*json.RawMessage类型的Go值

  • 问题内容: 我有pyspark数据框,其中包含名为 Filters 的列:“ array>” 我想将数据帧保存在csv文件中,为此,我需要将数组转换为字符串类型。 我尝试将其强制转换为:和,但是这两种解决方案都会为“过滤器”列中的每一行生成错误消息: 代码如下 样本JSON数据: 谢谢 !! 问题答案: 我创建了一个样本JSON数据集来匹配该模式: 使用explode()函数可以最佳化解决您的问题