获取 JSON 动态键名作为字符串?

huangapple go评论90阅读模式
英文:

Getting json dynamic key name as string?

问题

例如:

{"id":
    {"12345678901234":
       {"Account":"asdf",
       "Password":"qwerty"
       "LastSeen":"1397621470",
       }
    }
}

我一直在尝试编写一个程序,需要将id作为字符串获取,然后稍后使用它来检查LastSeen中的时间。我尝试使用simplejsonjsonq,但仍然无法弄清楚如何做到这一点。

英文:

For example:

{"id":
    {"12345678901234":
       {"Account":"asdf",
       "Password":"qwerty"
       "LastSeen":"1397621470",
       }
    }
}

A program I've been trying to make needs to get the id as a string and then later use it to check the time in LastSeen.
I've tried using simplejson and jsonq,but still cant figure out how to do that.

答案1

得分: 3

你可以使用RawMessage来简化代码(play with it) :

package main

import (
	"encoding/json"
	"fmt"
)

var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)

type Message struct {
	Id   string
	Info struct {
		Account  string
		Password string
		LastSeen string
	}
}

func main() {
	var (
		tmpmsg struct {
			Data map[string]json.RawMessage `json:"id"`
		}
		msg Message
	)
	if err := json.Unmarshal(data, &tmpmsg); err != nil {
		panic(err) //you probably wanna use or something instead
	}

	for id, raw := range tmpmsg.Data {
		msg.Id = id
		if err := json.Unmarshal(raw, &msg.Info); err != nil {
			panic(err)
		}
	}
	fmt.Printf("%+v\n", msg)

}
英文:

You can use RawMessage and make it much simpiler (play with it) :

package main

import (
	"encoding/json"
	"fmt"
)

var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)

type Message struct {
	Id   string
	Info struct {
		Account  string
		Password string
		LastSeen string
	}
}

func main() {
	var (
		tmpmsg struct {
			Data map[string]json.RawMessage `json:"id"`
		}
		msg Message
	)
	if err := json.Unmarshal(data, &tmpmsg); err != nil {
		panic(err) //you probably wanna use or something instead
	}

	for id, raw := range tmpmsg.Data {
		msg.Id = id
		if err := json.Unmarshal(raw, &msg.Info); err != nil {
			panic(err)
		}
	}
	fmt.Printf("%+v\n", msg)

}

答案2

得分: 1

在Golang博客上关于JSON的文章中,可以使用encoding/json包来实现。我创建了一个小程序来实现这个功能,代码如下:

package main

import (
    "encoding/json"
    "fmt"
)

var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)

type Message struct {
    id string
    LastSeen int64
} 

var m Message

func main() {
    var i interface {}
    err := json.Unmarshal(data, &i)
    if err != nil {
        println("Error decoding data")
        fmt.Printf("%s", err.Error())
        return
    }
    m := i.(map[string]interface{})

    for k, v := range m {
        println(k)
        im := v.(map[string]interface{})
        for ik, iv := range im {
            println("\t", ik)
            jm := iv.(map[string]interface{})
            for jk, jv := range jm {
                println("\t\t", jk, ": ", jv.(string))
            }
        }
    }
}

如果这段代码在Go的最佳实践方面存在问题,我向你道歉,因为我对这门语言还不熟悉。我知道其中有一些部分并不是完全必要的,比如Message类型的定义,但至少在你的数据上是可以工作的。

英文:

Looking at the Golang blog post on JSON <a href="http://blog.golang.org/json-and-go">here</a> it can be done using the encoding/json package. I created a small program to do this as follows:

package main

import (
    &quot;encoding/json&quot;
    &quot;fmt&quot;
)

var data []byte = []byte(`{&quot;id&quot;: {&quot;12345678901234&quot;: {&quot;Account&quot;:&quot;asdf&quot;, &quot;Password&quot;:&quot;qwerty&quot;, &quot;LastSeen&quot;:&quot;1397621470&quot;}}}`)

type Message struct {
    id string
    LastSeen int64
} 

var m Message

func main() {
    var i interface {}
    err := json.Unmarshal(data, &amp;i)
    if err != nil {
        println(&quot;Error decoding data&quot;)
        fmt.Printf(&quot;%s&quot;, err.Error())
        return
    }
    m := i.(map[string]interface{})

    for k, v := range m {
        println(k)
        im := v.(map[string]interface{})
        for ik, iv := range im {
            println(&quot;\t&quot;, ik)
            jm := iv.(map[string]interface{})
            for jk, jv := range jm {
                println(&quot;\t\t&quot;, jk, &quot;: &quot;, jv.(string))
            }
        }
    }
}

I apologise if this is poor in terms of Go best practices and such, I am new to the language. And I know that some elements of this aren't entirely necessary like the Message type definition but this works, at least on your data.

huangapple
  • 本文由 发表于 2014年4月25日 18:33:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/23290618.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定