将json字符串解组为具有结构本身的一个元素的结构 [英] Unmarshal json string to a struct that have one element of the struct itself

查看:85
本文介绍了将json字符串解组为具有结构本身的一个元素的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这里是struct

  type DBS struct {
URL字符串`json:url`
端口字符串`json:port`
Uname string`json:uname`
传递字符串`json:pass`
Authdb字符串`json:authdb`
副本[] 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
$ b $ / code>

该函数返回

  {[]} 


解决方案

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



replicaps是一个带有不同键的对象的JSON数组,其值可由 DBS 表示。



因此,要充分描述您的JSON,您需要某种动态类型。例如,一个映射就是这样一个动态类型。因此,您的原始JSON输入可以用类型完全建模: [] map [string] DBS 。这是一部分地图,因为您的JSON输入包含JSON数组。 map键可以为任何属性名称建模,并且该值是由 DBS 结构建模的JSON对象。



查看这个完全解析JSON输入的例子:

  type DBS struct {
URL字符串`json:url
端口字符串`json:port`
Unname字符串`json:uname`
传递字符串`json:pass`
Authdb字符串`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)。

p>输出(在
去游乐场试试):



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

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

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

type DBS struct {
URL字符串`json:url`
端口字符串`json:port`
Uname字符串`json:uname`
Pass字符串`json:pass`
Authdb字符串`json:authdb`
副本[] 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 \\\
,name,replica)
}
}
}

输出(在去游乐场试试):

 & {URL:mongodb:// localhost端口: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端口:27002 Uname :Pass:Authdb:Replicas:[]}


I am go beginner and trying to unmarshal the following json string

[{
    "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": ""
                }
            }
        ]
    }
}]

here is the struct

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`
}

and here is the function

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
}

The function is returning

{     []}

解决方案

Your JSON input is not a slice of DBS, as there is another JSON object wrapper, and a value of DBS belongs to the property "db".

Going deeper, the "replicaps" is a JSON array with objects holding varying keys, their values being representable by DBS.

So to fully describe your JSON, you need some kind of "dynamic" type. A map is such a dynamic type for example.

So your original JSON input can be fully modeled with the type: []map[string]DBS. It's a slice of maps, as your JSON input contains a JSON array. And the map key can model any property name, and the value is a JSON object modeled by the DBS struct.

See this example which fully parses the JSON input:

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)
}

Note the proper tag syntax (e.g. json:"url").

Output (try it on the Go Playground):

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

Note that you can further model the first level which is always "db", and we can switch to pointers (I used non-pointers in the first example so the printed result is readable):

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)
        }
    }
}

Output (try it on the 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字符串解组为具有结构本身的一个元素的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆