0

i cannot parse the json value i am sending a playground link Any idea about that? here is the link and codes

https://play.golang.org/p/qhZpS_-618s

package main

import (
    "encoding/json"
    "fmt"
    //mapstructure "github.com/mitchellh/mapstructure"

)

type presence struct{
    id string 
    m_type string 
    deny string 
}
type jsonHandler struct {
    name string 
    dat map[string]interface{}

}   

func main() {
    s := `["Presence",{"id":"[email protected]","type":"unavailable","deny":true}]`
    data := jsonHandler{}
    json.Unmarshal([]byte(s), &data)
    fmt.Printf("Operation: %s", data.name)


}

Output : Operation: Program exited.

3
  • Does this answer your question? json.Unmarshal returning blank structure Commented Dec 24, 2019 at 13:38
  • not worked @Peter play.golang.org/p/7d62N3BVan9 Commented Dec 24, 2019 at 13:58
  • solved i add solution Commented Dec 24, 2019 at 15:17

3 Answers 3

1

Try with this one: https://play.golang.com/p/UICf_uNNFdC

I've commented a lot in order to enhance code readability. Be sure to handle error properly and remove debug print.

package main

import (
    "encoding/json"
    "log"
    "strings"
)

type Presence struct {
    Presence string
    ID       string `json:"id"`
    Type     string `json:"type"`
    Deny     bool   `json:"deny"`
}

type JsonHandler struct {
    Name string   `json:"name"`
    Dat  Presence `json:"dat"`
}

func main() {
    var (
        // Used for unmarshal a given json
        packedData []json.RawMessage
        err        error
        // Data that does not have a related json key
        name []byte
        // Used for extract the raw data that will be unmarshalled into the Presence struct
        temp []byte
        // Nested json
        jsonPresence Presence
        handler      JsonHandler
    )

    s := `["Presence",{"id":"[email protected]","type":"unavailable","deny":true}]`

    log.Println("Dealing with -> " + s)

    // Unmarshall into a raw json message
    err = json.Unmarshal([]byte(s), &packedData)
    if err != nil {
        panic(err)
    }

    // Extract the presence
    log.Println("Presence: ", string(packedData[0]))
    // Extract the nested json
    log.Println("Packed: ", string(packedData[1]))

    // NOTE: 0 refers to the first value of the JSON
    name, err = packedData[0].MarshalJSON()
    if err != nil {
        panic(err)
    }
    log.Println("Value that does not have a key: " + string(name))
    handler.Name = strings.Replace(string(name), "\"", "", -1)

    // NOTE: 1 refers to the second value of the JSON, the entire JSON
    // Unmarshal the nested Json into byte
    temp, err = packedData[1].MarshalJSON()
    if err != nil {
        panic(err)
    }

    // Unmarshal the raw byte into the struct
    err = json.Unmarshal(temp, &jsonPresence)
    if err != nil {
        panic(err)
    }

    log.Println("ID:", jsonPresence.ID)
    log.Println("Type:", jsonPresence.Type)
    log.Println("Deny:", jsonPresence.Deny)

    handler.Dat = jsonPresence

    log.Println("Data unmarshalled: ", handler)
}
Sign up to request clarification or add additional context in comments.

1 Comment

we are simply parse ["Presence",{"id":"[email protected]","type":"unavailable","deny":true}] bro these codes too complicated and too much for this json... there must be a short way (2,3 lines codes) to do that by experiencing 7 years of software developer
1

Go Playground Link: https://play.golang.org/p/qe0jyFVNTH1

Few Problem are present in this:

1. Json Package can't refer the Unexported Structure Elements.So please use Deny instead of deny in the following snippet.This is applicable to all variables declared inside the structure

2. The json fields tag are incorrect. eg.mapstructure:"id" should be json:"id"

3. The json to be parsed contains two distinct elements i.e string "Presence" and nested json object.It can't be parsed as a single element.It is better to declare "Presence" as a key and nested json as the value.

4. The deny variable should be bool rather than string

4 Comments

Well,i want to parse ["Presence",{"id":"[email protected]","type":"unavailable","deny":true}] not you provided to me {"Presence":{"id":"[email protected]","type":"unavailable","deny":true}} so your comment doesn't mean anything to me because i receive this json from whatsapp socket please answer the question accourding to json array of : ["Presence",{"id":"[email protected]","type":"unavailable","deny":true}]
@user3236289 your Json is not a valid Json. Also answer is true. To unmarshall Json, export your struct fields. So use capital letters. Also do not use "mapstructure". And why "jsonHandler" struct has name and dat fields. They are not related with Json data. Maybe you should explain deeply.
my json is correct not wrong format.it comes from whatsapp socket okay? here parsed version of my json dropbox.com/s/0asnrkkinhfh2ke/…
@user3236289 Depending on your use case, Any direct method won't be applicable in this scenario.Either you have to parse data into json.RawMessage(as shown by @alessiosavi) or an interface{} and then implement a custom logic. Using custom unmarshaler is also a good option. kindly go through this article link by Marko Mikulicic. You will have some clarity about the possible solutions.
1

Wow,solved problem by adding only these codes

Here Go Lang Link : https://play.golang.org/p/doHNWK58Cae

func (n *JsonHandler) UnmarshalJSON(buf []byte) error {
    tmp := []interface{}{&n.Name, &n.Dat}
    wantLen := len(tmp)
    if err := json.Unmarshal(buf, &tmp); err != nil {
        return err
    }
    if g, e := len(tmp), wantLen; g != e {
        return fmt.Errorf("wrong number of fields in Notification: %d != %d", g, e)
    }
    return nil
}

1 Comment

+1 very clean! Have you tested the performance of the two solution? I think that this one is more optimized than my solution in terms of speed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.