在<code>go</code>中,标准包编码/json公开了<code>json。Unmarshal函数解析JSON。
可以在预定义的结构
中取消封送 JSON 字符串,也可以使用接口 {}
并迭代意外 JSON 数据结构的结果。
也就是说,我无法正确解析复杂的 JSON。有人可以告诉我如何实现这一目标吗?
{
"k1" : "v1",
"k2" : "v2",
"k3" : 10,
"result" : [
[
["v4", v5, {"k11" : "v11", "k22" : "v22"}]
, ... ,
["v4", v5, {"k33" : "v33", "k44" : "v44"}
]
],
"v3"
]
}
我写过JSON和Go的文章,结果发现Case int
不起作用,现在需要是Case Float64
,并且在现实世界的JSON中有很多嵌套。
> go version
go version go1.7.1 darwin/amd64
我还研究了Go中的JSON解码,但它对我没有太大帮助,因为我需要通过绑定将它转换成一系列对mruby的调用,并且那篇文章的作者在很大程度上对Go结构感到满意。
我花了一点时间来处理这个问题,最后的迭代转储器函数如下所示:
func dumpJSON(v interface{}, kn string) {
iterMap := func(x map[string]interface{}, root string) {
var knf string
if root == "root" {
knf = "%q:%q"
} else {
knf = "%s:%q"
}
for k, v := range x {
dumpJSON(v, fmt.Sprintf(knf, root, k))
}
}
iterSlice := func(x []interface{}, root string) {
var knf string
if root == "root" {
knf = "%q:[%d]"
} else {
knf = "%s:[%d]"
}
for k, v := range x {
dumpJSON(v, fmt.Sprintf(knf, root, k))
}
}
switch vv := v.(type) {
case string:
fmt.Printf("%s => (string) %q\n", kn, vv)
case bool:
fmt.Printf("%s => (bool) %v\n", kn, vv)
case float64:
fmt.Printf("%s => (float64) %f\n", kn, vv)
case map[string]interface{}:
fmt.Printf("%s => (map[string]interface{}) ...\n", kn)
iterMap(vv, kn)
case []interface{}:
fmt.Printf("%s => ([]interface{}) ...\n", kn)
iterSlice(vv, kn)
default:
fmt.Printf("%s => (unknown?) ...\n", kn)
}
}
由于 b
是一个字节片,其中 JSON 表示数组或顶层的对象,您可以像这样调用它:
var f interface{}
if err := json.Unmarshal(b, &f); err != nil {
panic(err)
}
dumpJSON(f, "root")
希望这有所帮助,你可以试试这里的comple程序。
我建议不要自己做,除非你觉得你必须学习围棋类型的工作原理,使用reflect
会让你觉得自己是宇宙的主人(就我个人而言,reflect
让我抓狂)。
正如@changingrainbows在下面指出的那样,有github。com/tidwall/gjson
包,它似乎包装了encoding/json<-code>,并使用
,它非常难使用,内部工作非常复杂。反射
。我可能和<code>github没什么不同。com/mitchellh/reflectwalk
我已经使用github.com/buger/jsonparser
相当广泛地在我的一个项目中,还有github.com/json-iterator/go
,我还没有尝试过,但它似乎是基于github.com/buger/jsonparser
,并似乎公开了enconding/json
-兼容的接口,并有func get(data[]byte, path…接口{})任何
以及。为了记录,库伯斯内特项目最近切换到github.com/json-iterator/go
。在我的项目中,我使用编码/json
以及github.com/buger/jsonparser
,我可能会切换到github.com/json-iterator/go
当我有时间的时候。我会试着用更多的发现来更新这篇文章。
最近,gjson在json中提供了属性选择
k1 := gjson.Get(json, "k1")
k33 : = gjson.Get(json, "result.#.#.k33")
引用自JSON和Go:
在不知道此数据结构的情况下,我们可以使用Unmarshal将其解码为接口{}值:
b := []byte(`{
"k1" : "v1",
"k3" : 10,
result:["v4",12.3,{"k11" : "v11", "k22" : "v22"}]
}`)
var f interface{}
err := json.Unmarshal(b, &f)
此时,f中的Go值将是一个映射,其键为字符串,其值本身存储为空接口值:
f = map[string]interface{}{
"k1": "v1",
"k3": 10,
"result": []interface{}{
"v4",
12.3,
map[string]interface{}{
"k11":"v11",
"k22":"v22",
},
},
}
要访问此数据,我们可以使用类型断言访问f
的底层map[string]接口{}:
m := f.(map[string]interface{})
然后,我们可以使用范围语句遍历map并使用类型开关将其值作为具体类型访问:
for k, v := range m {
switch vv := v.(type) {
case string:
fmt.Println(k, "is string", vv)
case int:
fmt.Println(k, "is int", vv)
case []interface{}:
fmt.Println(k, "is an array:")
for i, u := range vv {
fmt.Println(i, u)
}
default:
fmt.Println(k, "is of a type I don't know how to handle")
}
}
通过这种方式,您可以处理未知的JSON数据,同时还可以享受类型安全的好处。
有关Go和JSON的更多信息可以在原始文章中找到。我稍微更改了代码片段,以更类似于问题中的JSON。
问题内容: 我正在寻找一种将复杂文本文件解析为pandas DataFrame的简单方法。下面是一个示例文件,我希望解析后的结果是什么样,以及我当前的方法。 有什么方法可以使其更简洁/更快/更pythonic /更易读? 我也把这个问题放在了Code Review上 。 我最终写了一篇博客文章向初学者解释。 这是一个示例文件: 这是我希望解析后的结果看起来像什么: 这是我目前解析的方式: 问题答案
我收到了一个包含字符串和元组元素组合的CSV文件,但找不到正确解析它的方法。我错过了什么明显的东西吗? csvfile 第一行是标题,第二行开始数据 产量: csv.reader解析每行不同,因为结构复杂,嵌入了花括号元素。 ...但是我希望每行有20个元素。
我从一个复杂的json中获取空数据,这里是json。当我试图解析它时,我得到了null。请看一看。 我已生成模型类:https://javiercbk.github.io/json_to_dart/ 生成模型类后,创建一个新的类名ModelClass。 另一个类名为APiResponse并编写代码:这个类获取api响应并返回响应:APiResponse。fromJson(jsonDecode(re
问题内容: 是否可以对JSON对象执行复杂的查询?我愿意接受JavaScript或jQuery解决方案,越轻松越好。我正在构想某种类似于LINQ或SQL的功能编程语言。 我不希望其他任何第三方库或附加组件。 更新 从早期答案的外观来看,将需要一个附加组件。在这种情况下,我更喜欢不需要安装过程的加载项。随软件发布一起部署的东西(如jQuery)很好(例如* .js文件集)。 问题答案: 签出:是否有
问题内容: 我有一个很长的JSON与Gson一起解析,但是为了简洁起见,我将其修剪为以下示例: 从SO和其他几个地方,我发现我需要定义一个顶级容器,例如下面的容器,但我不知道如何完成其定义 然后每堂课 我正在尝试解析它,这是到目前为止我编写的代码: JSON字符串存储在名为response的变量中 我的最终要求是of,并且关联。 问题答案: 第一个问题 :您的需求是: 它不必是静态的。 第二个