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

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

Parse unstructured json in golang

问题

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

res,err := http.Get("url_of_server")
[
    [
        {
            "id": "1",
            "text": "sample text",
            "user": {
                "user_id": "1",
                "username": "user1"
            },
            "created_at_utc": "2022-12-20T16:38:06+00:00",
            "status": "Active"
        },
        {
            "id": "2",
            "text": "sample text",
            "user": {
                "user_id": "2",
                "username": "user2"
            },
            "created_at_utc": "2022-12-01T10:15:00+00:00",
            "status": "Active"
        }
    ],
    "{\"code\": \"hsdvnkvuahudvhafdlfv\", \"is_updated\": true}",
    null
]

我想要获取的是:

[
    {
        "id": "1",
        "text": "sample text",
        "user": {
            "user_id": "1",
            "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
    },
    {
        "id": "2",
        "text": "sample text",
        "user": {
            "user_id": "2",
            "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
    }
]

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

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

"{\"code\": \"hsdvnkvuahudvhafdlfv\", \"is_updated\": true}",
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)

res,err := http.Get("url_of_server")
[[
    {
        "id": "1",
        "text": "sample text",
        "user": {
          "user_id": "1",
          "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
      },
      {
        "id": "2",
        "text": "sample text",
        "user": {
          "user_id": "2",
          "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
      }
],
"{"code": "hsdvnkvuahudvhafdlfv",
  "is_updated": true}", 
 null
]

what i want to get is:

[
    {
        "id": "1",
        "text": "sample text",
        "user": {
          "user_id": "1",
          "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
      },
      {
        "id": "2",
        "text": "sample text",
        "user": {
          "user_id": "2",
          "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
      }
]

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:

"{"code": "hsdvnkvuahudvhafdlfv",
  "is_updated": true}", 
 null

答案1

得分: 3

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

type Item struct {
    ID   string `json:"id"`
    Text string `json:"text"`
    User struct {
        UserID   string `json:"user_id"`
        Username string `json:"username"`
    } `json:"user"`
    CreatedAtUtc time.Time `json:"created_at_utc"`
    Status       string    `json:"status"`
}

声明一个项目的切片:

var items []Item

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

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

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

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

在GoLang PlayGround中运行代码

英文:

Declare a type for the items:

type Item struct {
	ID   string `json:"id"`
	Text string `json:"text"`
	User struct {
		UserID   string `json:"user_id"`
		Username string `json:"username"`
	} `json:"user"`
	CreatedAtUtc time.Time `json:"created_at_utc"`
	Status       string    `json:"status"`
}

Declare a slice of the items:

var items []Item

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

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.

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

Run the code in the GoLang PlayGround.

答案2

得分: 3

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

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

使用gjson的示例代码:

package main

import (
   "fmt"
   "github.com/tidwall/gjson"
)

const textInput = `[[
    {
        "id": "1",
        "text": "sample text",
        "user": {
          "user_id": "1",
          "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
      },
      {
        "id": "2",
        "text": "sample text",
        "user": {
          "user_id": "2",
          "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
      }
],
"{\"code\": \"hsdvnkvuahudvhafdlfv\",
  \"is_updated\": true}", 
 null
]`

func main() {
    jsonBody := gjson.Parse(textInput)
    fmt.Println(jsonBody.Get("0"))
}
英文:

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:

package main

import (
   "fmt"
   "github.com/tidwall/gjson"
)

const textInput = `[[
    {
        "id": "1",
        "text": "sample text",
        "user": {
          "user_id": "1",
          "username": "user1"
        },
        "created_at_utc": "2022-12-20T16:38:06+00:00",
        "status": "Active"
      },
      {
        "id": "2",
        "text": "sample text",
        "user": {
          "user_id": "2",
          "username": "user2"
        },
        "created_at_utc": "2022-12-01T10:15:00+00:00",
        "status": "Active"
      }
],
"{"code": "hsdvnkvuahudvhafdlfv",
  "is_updated": true}", 
 null
]`

func main() {
    jsonBody := gjson.Parse(textInput)
    fmt.Println(jsonBody.Get("0"))
}

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:

确定