Home > Mobile >  Parse unstructured json in golang
Parse unstructured json in golang

Time:12-21

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

CodePudding user response:

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.

CodePudding user response:

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"))
}
  • Related