一个Go写的JSON表达式工具

elgs 发布于 2015年12月30日
tinyfool 等1人欣赏。

为了解决用户输入表达式分析数据的功能,我写了一个Go的JSON表达式分析工具,希望对用Golang的同学有用。

https://github.com/elgs/gojq

gojq

JSON query in Golang.

Install

go get -u github.com/elgs/gojq

This library serves two purposes:

  • enables JSON expression evaluation
  • reduces the pain of type assertion parsing JSON

Query from JSON Object

package main

import (
    "fmt"
    "github.com/elgs/gojq"
)

var jsonObj = `
{
  "name": "sam",
  "gender": "m",
  "pet": null,
  "skills": [
    "Eating",
    "Sleeping",
    "Crawling"
  ]
}
`

func main() {
    parser, err := gojq.NewStringQuery(jsonObj)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(parser.Parse("name"))       // sam <nil>
    fmt.Println(parser.Parse("gender"))     // m <nil>
    fmt.Println(parser.Parse("skills.[1]")) // Sleeping <nil>
    fmt.Println(parser.Parse("hello"))      // <nil> hello does not exist.
    fmt.Println(parser.Parse("pet"))        // <nil> <nil>
}

Query from JSON Array

package main

import (
    "fmt"
    "github.com/elgs/gojq"
)

var jsonArray = `
[
  {
    "name": "elgs",
    "gender": "m",
    "skills": [
      "Golang",
      "Java",
      "C"
    ]
  },
  {
    "name": "enny",
    "gender": "f",
    "skills": [
      "IC",
      "Electric design",
      "Verification"
    ]
  },
  {
    "name": "sam",
    "gender": "m",
    "pet": null,
    "skills": [
      "Eating",
      "Sleeping",
      "Crawling"
    ]
  }
]
`

func main() {
    parser, err := gojq.NewStringQuery(jsonArray)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(parser.Parse("[0].name"))       // elgs <nil>
    fmt.Println(parser.Parse("[1].gender"))     // f <nil>
    fmt.Println(parser.Parse("[2].skills.[1]")) // Sleeping <nil>
    fmt.Println(parser.Parse("[2].hello"))      // <nil> hello does not exist.
    fmt.Println(parser.Parse("[2].pet"))        // <nil> <nil>
}

Netsted Query

package main

import (
    "fmt"
    "github.com/elgs/gojq"
)

var jsonArray = `
[
  {
    "name": "elgs",
    "gender": "m",
    "skills": [
      "Golang",
      "Java",
      "C"
    ]
  },
  {
    "name": "enny",
    "gender": "f",
    "skills": [
      "IC",
      "Electric design",
      "Verification"
    ]
  },
  {
    "name": "sam",
    "gender": "m",
    "pet": null,
    "skills": [
      "Eating",
      "Sleeping",
      "Crawling"
    ]
  }
]
`

func main() {
    parser, err := gojq.NewStringQuery(jsonArray)
    if err != nil {
        fmt.Println(err)
        return
    }
    samSkills, err := parser.Parse("[2].skills")
    fmt.Println(samSkills, err) //[Eating Sleeping Crawling] <nil>
    samSkillParser := gojq.NewQuery(samSkills)
    fmt.Println(samSkillParser.Parse("[1]")) //Sleeping <nil>
}
共12条回复
tinyfool 回复于 2015年12月30日

先给你点个赞,你现在用Go做啥?

brambles 回复于 2015年12月30日

为什么不直接解析成对象呢?

elgs 回复于 2015年12月30日

1楼 @tinyfool 我在做一个叫Net Data的项目,本来准备年底发布的。但现在才刚刚写完,发布要推迟到1月了。

elgs 回复于 2015年12月30日

2楼 @brambles 你是说解析成 Int, string... 类型吗?因为不知道是什么类型,这个工具可以用来解析JSON配置文件。我有一个现实的需求需要提供给通过用户输入查询JSON的内容。

tinyfool 回复于 2015年12月30日

3楼 @elgs 做啥的?

elgs 回复于 2015年12月30日

5楼 @tinyfool 是一个数据库API的网站,我们用它做Web和Mobile应用的后台。前几天录了一点视频 https://www.youtube.com/playlist?list=PL0z6IcKw1DuaUhgJVoRafMyT8iIZB5gMF,但声音实在太差了。

tinyfool 回复于 2015年12月30日

6楼 @elgs 好玩,声音挺好,我正在看

elgs 回复于 2015年12月30日

7楼 @tinyfool 现在我还在做一个远程推送通知的功能,当数据发生变化的时候可以通知用户自定义的URL。这个功能加上去,再做一集视屏,就可以发布了。

elgs 回复于 2015年12月30日

7楼 @tinyfool 录视频真是累活,第一集我感觉我录了一百遍。但后面就好一点了。

tinyfool 回复于 2015年12月31日

8楼 @elgs 有点意思,现在有啥跟你们类似的东西么?

9楼 @elgs 恩,学啥都很好玩,录视频也很有意思,我未来还准备录一些教育视频

brambles 回复于 2015年12月31日

4楼 @elgs

不知道是什么类型就封装一下嘛……前段时间花了一下个下午用vimscript造了一个json 的 parser……

讲一下我的思路。

1 Json基本类型: Number / String / Boolean / Null 2 Json的复合类型: [item1, item2, item3...] / {"key1": item1, "key2": item2}

首先构建一个 JsonBase 的基类,有一个 getValue 方法。

构建 JsonNumber / JsonString / JsonBoolean / JsonNull 类继承自JsonBase,拿来存储具体的数值。构建 JsonObject / JsonArray 类同样继承自JsonBase,拿来构造树状结构,并且有一个query方法用来查找值。

(当然,动态语言和拥有代数数据类型的函数式语言都不会这么麻烦,静态还是面向对象语言就真是日了doge了)

elgs 回复于 2015年12月31日

11楼 @brambles 你的做法很好。我也想过弄一个JSONBase类,然后里面有AsInt, AsString, AsBool, and etc. 但我后来还是决定直接用interface{},有两个原因。 1. 如果别人用这个库,我不想增加一个我的类型。当然我说这话有点shameless,这只是个人喜好,并不代表我的做法是对的,你说的是错的。 2. 我的目的是实现一个类似Bash里jq的东西,这个目的达到了,我也就没有折腾了。

我在用一个叫swift-json的库,这是一个Swift的JSON库,他们的做法和你说的一样。我其实很喜欢这些方便的方法。

本帖有12个回复,因为您没有注册或者登录本站,所以,只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。

登录 或者 注册
[顶 楼]
|
|
[底 楼]
|
|
[首 页]