在Go语言中解析非结构化的JSON数据。

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

Parse unstructured json in golang

问题

有没有办法解析一个非结构化的 JSON(文本)数据?下面是一个我想要解析和访问数据(内部列表)的网络请求的示例响应:

  1. res,err := http.Get("url_of_server")
  1. [
  2. [
  3. {
  4. "id": "1",
  5. "text": "sample text",
  6. "user": {
  7. "user_id": "1",
  8. "username": "user1"
  9. },
  10. "created_at_utc": "2022-12-20T16:38:06+00:00",
  11. "status": "Active"
  12. },
  13. {
  14. "id": "2",
  15. "text": "sample text",
  16. "user": {
  17. "user_id": "2",
  18. "username": "user2"
  19. },
  20. "created_at_utc": "2022-12-01T10:15:00+00:00",
  21. "status": "Active"
  22. }
  23. ],
  24. "{\"code\": \"hsdvnkvuahudvhafdlfv\", \"is_updated\": true}",
  25. null
  26. ]

我想要获取的是:

  1. [
  2. {
  3. "id": "1",
  4. "text": "sample text",
  5. "user": {
  6. "user_id": "1",
  7. "username": "user1"
  8. },
  9. "created_at_utc": "2022-12-20T16:38:06+00:00",
  10. "status": "Active"
  11. },
  12. {
  13. "id": "2",
  14. "text": "sample text",
  15. "user": {
  16. "user_id": "2",
  17. "username": "user2"
  18. },
  19. "created_at_utc": "2022-12-01T10:15:00+00:00",
  20. "status": "Active"
  21. }
  22. ]

在 Python 中,可以通过简单地使用 res.json()[0] 来实现。

我尝试过使用 json.Unmarshal() 转换为 map 和 struct,但不起作用,我不知道如何去掉响应的这部分:

  1. "{\"code\": \"hsdvnkvuahudvhafdlfv\", \"is_updated\": true}",
  2. null
英文:

Is there any solution to parse an unstructured json(text) data?
below is a sample response of a web requst that i want to parse and access data (the inner list)

  1. res,err := http.Get("url_of_server")
  1. [[
  2. {
  3. "id": "1",
  4. "text": "sample text",
  5. "user": {
  6. "user_id": "1",
  7. "username": "user1"
  8. },
  9. "created_at_utc": "2022-12-20T16:38:06+00:00",
  10. "status": "Active"
  11. },
  12. {
  13. "id": "2",
  14. "text": "sample text",
  15. "user": {
  16. "user_id": "2",
  17. "username": "user2"
  18. },
  19. "created_at_utc": "2022-12-01T10:15:00+00:00",
  20. "status": "Active"
  21. }
  22. ],
  23. "{"code": "hsdvnkvuahudvhafdlfv",
  24. "is_updated": true}",
  25. null
  26. ]

what i want to get is:

  1. [
  2. {
  3. "id": "1",
  4. "text": "sample text",
  5. "user": {
  6. "user_id": "1",
  7. "username": "user1"
  8. },
  9. "created_at_utc": "2022-12-20T16:38:06+00:00",
  10. "status": "Active"
  11. },
  12. {
  13. "id": "2",
  14. "text": "sample text",
  15. "user": {
  16. "user_id": "2",
  17. "username": "user2"
  18. },
  19. "created_at_utc": "2022-12-01T10:15:00+00:00",
  20. "status": "Active"
  21. }
  22. ]

in python it is possible by easily using res.json()[0]

I have tried using json.Unmarshal() to a map and also struct but does not work,
i don't know how to get rid of this part of response:

  1. "{"code": "hsdvnkvuahudvhafdlfv",
  2. "is_updated": true}",
  3. null

答案1

得分: 3

声明一个用于项目的类型:

  1. type Item struct {
  2. ID string `json:"id"`
  3. Text string `json:"text"`
  4. User struct {
  5. UserID string `json:"user_id"`
  6. Username string `json:"username"`
  7. } `json:"user"`
  8. CreatedAtUtc time.Time `json:"created_at_utc"`
  9. Status string `json:"status"`
  10. }

声明一个项目的切片:

  1. var items []Item

声明一个表示整个JSON的切片。第一个元素是项目。

  1. var v = []interface{}{&items}

将数据解析到v中。items切片将包含你要查找的值。v的第二个和第三个元素将包含你要忽略的值。

  1. err := json.Unmarshal(data, &v)

在GoLang PlayGround中运行代码

英文:

Declare a type for the items:

  1. type Item struct {
  2. ID string `json:"id"`
  3. Text string `json:"text"`
  4. User struct {
  5. UserID string `json:"user_id"`
  6. Username string `json:"username"`
  7. } `json:"user"`
  8. CreatedAtUtc time.Time `json:"created_at_utc"`
  9. Status string `json:"status"`
  10. }

Declare a slice of the items:

  1. var items []Item

Declare a slice representing the entire JSON thing. The first element is the items.

  1. var v = []any{&items}

Unmarshal to v. The items slice will have the values that you are looking for. The second and third elements of v will contain the values you want to ignore.

  1. err := json.Unmarshal(data, &v)

Run the code in the GoLang PlayGround.

答案2

得分: 3

Go的标准JSON库在处理意外或不受控制的输入时不如其他库灵活。

一个很好的替代方案是tidwall的gjson

使用gjson的示例代码:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/tidwall/gjson"
  5. )
  6. const textInput = `[[
  7. {
  8. "id": "1",
  9. "text": "sample text",
  10. "user": {
  11. "user_id": "1",
  12. "username": "user1"
  13. },
  14. "created_at_utc": "2022-12-20T16:38:06+00:00",
  15. "status": "Active"
  16. },
  17. {
  18. "id": "2",
  19. "text": "sample text",
  20. "user": {
  21. "user_id": "2",
  22. "username": "user2"
  23. },
  24. "created_at_utc": "2022-12-01T10:15:00+00:00",
  25. "status": "Active"
  26. }
  27. ],
  28. "{\"code\": \"hsdvnkvuahudvhafdlfv\",
  29. \"is_updated\": true}",
  30. null
  31. ]`
  32. func main() {
  33. jsonBody := gjson.Parse(textInput)
  34. fmt.Println(jsonBody.Get("0"))
  35. }
英文:

Go's standard JSON library is not as flexible as others when it comes to dealing with unexpected or uncontrolled input.

A great alternative is tidwall's gjson.

Example code with gjson:

  1. package main
  2. import (
  3. "fmt"
  4. "github.com/tidwall/gjson"
  5. )
  6. const textInput = `[[
  7. {
  8. "id": "1",
  9. "text": "sample text",
  10. "user": {
  11. "user_id": "1",
  12. "username": "user1"
  13. },
  14. "created_at_utc": "2022-12-20T16:38:06+00:00",
  15. "status": "Active"
  16. },
  17. {
  18. "id": "2",
  19. "text": "sample text",
  20. "user": {
  21. "user_id": "2",
  22. "username": "user2"
  23. },
  24. "created_at_utc": "2022-12-01T10:15:00+00:00",
  25. "status": "Active"
  26. }
  27. ],
  28. "{"code": "hsdvnkvuahudvhafdlfv",
  29. "is_updated": true}",
  30. null
  31. ]`
  32. func main() {
  33. jsonBody := gjson.Parse(textInput)
  34. fmt.Println(jsonBody.Get("0"))
  35. }

huangapple
  • 本文由 发表于 2022年12月21日 05:16:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/74868991.html
匿名

发表评论

匿名网友

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

确定