Golang中如何修改Gojq查询

Golang中如何修改Gojq查询 大家好,

我正在学习Go语言编程,并尝试使用GitHub - itchyny/gojq: Pure Go implementation of jq。我在如何从下面的API调用中提取id时遇到了困难。

{"id": 1553,
"node_id": "xxxxx",
"name": "xxxx-actions",
"full_name": "xxxx/xxxxx-actions",
"private": false,
"owner": {
"login": "xxxx",
"id": 4,
"node_id": "xxxxxx"
}
}

但我不知道如何修改这部分。

input := map[string]any{"foo": []any{1, 2, 3}}

我知道这对其他人来说可能看起来很简单,但我非常感谢社区能提供的任何帮助。提前感谢。

此致


更多关于Golang中如何修改Gojq查询的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

你好 Sean,

感谢你的回复,我是 Go 语言的新手,还在消化数据类型。

此致, Walter

更多关于Golang中如何修改Gojq查询的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好 Rm,

我原本想尝试让 gojq 运行起来,但你说得对,我只是想过滤一个 JSON 字符串。你的示例正好符合我的需求。

谢谢, Walter

以下是该代码的 Go Playground 链接:

Go Playground - Go 编程语言

Walter_Policarpio:

但我不知道如何修改这部分。

你能详细说明一下你不知道如何修改什么吗?你是在问如何获取README中的示例代码以便修改,还是想了解Go语言中map/切片的语法,或者是如何将你的示例JSON反序列化成map[string]any?又或者是其他问题?

Walter_Policarpio:

{"id": 1553,
"node_id": "xxxxx",
"name": "xxxx-actions",
"full_name": "xxxx/xxxxx-actions",
"private": false,
"owner": {
"login": "xxxx",
"id": 4,
"node_id": "xxxxxx"
}
}

我不太确定你为什么想在我的代码中使用 /itchyny/gojq —— 它确实是一个很棒的包。但如果你只是想修改 JSON 中的某个值——假设你有一个 JSON 字符串。你通过 http.Client 执行了一次 GET 请求,响应体包含了一个 JSON 字符串,现在你想修改这个字符串并将其作为 POST 请求的负载。这里我不会详述 http.Client 的部分,我们假设你已经有了这个 JSON 字符串。

package main

import (
	"fmt"

	"github.com/tidwall/gjson"
	"github.com/tidwall/pretty"
	"github.com/tidwall/sjson"
)

var jIn string = `{"id":1553,"node_id":"xxxxx","name":"xxxx-actions","full_name":"xxxx/xxxxx-actions","private":false,"owner":{"login":"xxxx","id":4,"node_id":"xxxxxx"}}`

func main() {
	var err error
	res := gjson.Get(jIn, "owner.login")
	fmt.Println(res.Str)
	if jIn, err = sjson.Set(jIn, "owner.login", "Superman"); err != nil {
		panic(err)
	}
	jOut := pretty.Pretty([]byte(jIn))
	fmt.Println(string(jOut))

}

虽然我也使用 /itchyny/gojq,但我处理 JSON 的主要工具是 tidwall (Josh Baker) · GitHub。请注意,在这个例子中,我不需要将 JSON 解析到结构体或映射中,而是直接对 jIn 这个 JSON 字符串进行操作。我使用 sjson 成功地将 owner.login 的值修改为了 Superman

在Gojq中提取JSON对象的id字段,可以通过以下方式实现:

package main

import (
    "encoding/json"
    "fmt"
    "github.com/itchyny/gojq"
)

func main() {
    // 原始JSON数据
    jsonStr := `{
        "id": 1553,
        "node_id": "xxxxx",
        "name": "xxxx-actions",
        "full_name": "xxxx/xxxxx-actions",
        "private": false,
        "owner": {
            "login": "xxxx",
            "id": 4,
            "node_id": "xxxxxx"
        }
    }`

    // 解析JSON到interface{}
    var input interface{}
    if err := json.Unmarshal([]byte(jsonStr), &input); err != nil {
        panic(err)
    }

    // 创建jq查询
    query, err := gojq.Parse(".id")
    if err != nil {
        panic(err)
    }

    // 执行查询
    iter := query.Run(input)
    for {
        v, ok := iter.Next()
        if !ok {
            break
        }
        if err, ok := v.(error); ok {
            panic(err)
        }
        fmt.Printf("id: %v\n", v)
    }
}

如果要从嵌套对象中提取owner的id,查询改为:

query, err := gojq.Parse(".owner.id")

对于数组中的多个对象,假设输入是对象数组:

jsonStr := `[
    {"id": 1553, "name": "repo1"},
    {"id": 1554, "name": "repo2"}
]`

query, err := gojq.Parse(".[].id")
// 输出:1553 1554

如果输入是map[string]any格式:

input := map[string]any{
    "id": 1553,
    "node_id": "xxxxx",
    "owner": map[string]any{
        "id": 4,
        "login": "xxxx",
    },
}

query, err := gojq.Parse(".id")
// 输出:1553

要同时提取多个字段:

query, err := gojq.Parse("{id, owner_id: .owner.id}")
// 输出:{"id": 1553, "owner_id": 4}

这些示例展示了如何使用Gojq从JSON结构中提取特定字段的值。

回到顶部