गो

2012-06-16 16 views
62

में एक मानचित्र में आंशिक JSON unmarshal मेरा वेबस्केट सर्वर प्राप्त होगा और अनमर्शल JSON डेटा प्राप्त करेगा। यह डेटा हमेशा किसी ऑब्जेक्ट में कुंजी/वैल्यू जोड़े के साथ लपेटा जाएगा। कुंजी-स्ट्रिंग मान पहचानकर्ता के रूप में कार्य करेगी, गो सर्वर को बताएगी कि यह किस तरह का मूल्य है। किस प्रकार का मूल्य जानने के बाद, मैं JSON unmarshal को सही प्रकार की संरचना में मान पर जा सकता हूं।गो

प्रत्येक जेसन-ऑब्जेक्ट में एकाधिक कुंजी/मान जोड़े हो सकते हैं।

उदाहरण JSON:

{ 
    "sendMsg":{"user":"ANisus","msg":"Trying to send a message"}, 
    "say":"Hello" 
} 

कोई आसान तरीका "encoding/json" पैकेज का उपयोग यह करने के लिए है?

package main 

import (
    "encoding/json" 
    "fmt" 
) 

// the struct for the value of a "sendMsg"-command 
type sendMsg struct { 
    user string 
    msg string 
} 
// The type for the value of a "say"-command 
type say string 

func main(){ 
    data := []byte(`{"sendMsg":{"user":"ANisus","msg":"Trying to send a message"},"say":"Hello"}`) 

    // This won't work because json.MapObject([]byte) doesn't exist 
    objmap, err := json.MapObject(data) 

    // This is what I wish the objmap to contain 
    //var objmap = map[string][]byte { 
    // "sendMsg": []byte(`{"user":"ANisus","msg":"Trying to send a message"}`), 
    // "say": []byte(`"hello"`), 
    //} 
    fmt.Printf("%v", objmap) 
} 

किसी भी प्रकार के सुझाव/सहायता के लिए धन्यवाद!

उत्तर

129

यह Unmarshalling द्वारा map[string]*json.RawMessage में पूरा किया जा सकता है।

var objmap map[string]*json.RawMessage 
err := json.Unmarshal(data, &objmap) 

आगे sendMsg पार्स करने के लिए, आप तो कर सकता है कुछ की तरह:

var s sendMsg 
err = json.Unmarshal(*objmap["sendMsg"], &s) 

say लिए, आप एक स्ट्रिंग में एक ही बात और unmarshal कर सकते हैं:

var str string 
err = json.Unmarshal(*objmap["say"], &str) 
+4

बिल्कुल सही! मुझे याद आया कि आप 'RawMessage' का उपयोग कैसे कर सकते हैं। वास्तव में मुझे क्या चाहिए। 'कहना' के बारे में, मैं वास्तव में इसे अभी भी 'json.RawMessage' के रूप में चाहता हूं, क्योंकि स्ट्रिंग अभी भी डीकोड नहीं किया गया है (' ''' 'और' \ n' अक्षर से बच निकला है), इसलिए मैं इसे भी अनमशल कर दूंगा। – ANisus

+1

I आपने जो किया उससे मेल खाने के लिए मेरा जवाब तय किया। धन्यवाद –

+3

प्रकार नक्शा होना चाहिए [स्ट्रिंग] * json.RawMessage इसके बजाय Unmarshal/मार्शल विधियों को जेसन पर लागू नहीं किया गया है। RawMessage। – albert

0

इसके अलावा करने के लिए स्टीफन वेनबर्ग के जवाब, मैंने बाद में iojson नामक एक आसान टूल लागू किया है, जो आसानी से डेटा को मौजूदा ऑब्जेक्ट में पॉप्युलेट करने में मदद करता है मौजूदा ऑब्जेक्ट को JSON स्ट्रिंग पर कोड करना। अन्य मिडवेयर के साथ काम करने के लिए एक इओजसन मिडलवेयर भी प्रदान किया जाता है। अधिक उदाहरणों को https://github.com/junhsieh/iojson

उदाहरण पाया जा सकता है:

func main() { 
    jsonStr := `{"Status":true,"ErrArr":[],"ObjArr":[{"Name":"My luxury car","ItemArr":[{"Name":"Bag"},{"Name":"Pen"}]}],"ObjMap":{}}` 

    car := NewCar() 

    i := iojson.NewIOJSON() 

    if err := i.Decode(strings.NewReader(jsonStr)); err != nil { 
     fmt.Printf("err: %s\n", err.Error()) 
    } 

    // populating data to a live car object. 
    if v, err := i.GetObjFromArr(0, car); err != nil { 
     fmt.Printf("err: %s\n", err.Error()) 
    } else { 
     fmt.Printf("car (original): %s\n", car.GetName()) 
     fmt.Printf("car (returned): %s\n", v.(*Car).GetName()) 

     for k, item := range car.ItemArr { 
      fmt.Printf("ItemArr[%d] of car (original): %s\n", k, item.GetName()) 
     } 

     for k, item := range v.(*Car).ItemArr { 
      fmt.Printf("ItemArr[%d] of car (returned): %s\n", k, item.GetName()) 
     } 
    } 
} 

नमूना उत्पादन:

car (original): My luxury car 
car (returned): My luxury car 
ItemArr[0] of car (original): Bag 
ItemArr[1] of car (original): Pen 
ItemArr[0] of car (returned): Bag 
ItemArr[1] of car (returned): Pen