अनमर्सलिंग ने JSON ऑब्जेक्ट्स को नेस्टेड किया


122

कर रहे हैं एक कुछ सवालों पर विषय लेकिन उनमें से कोई इस प्रकार मैं एक नया बनाने रहा हूँ, मेरे मामले को कवर करने लगते हैं।

मेरे पास JSON निम्नलिखित है:

{"foo":{ "bar": "1", "baz": "2" }, "more": "text"}

क्या नेस्टेड बार प्रॉपर्टी को अनमार्टस करने और नेस्टेड स्ट्रक्चर बनाए बिना इसे सीधे किसी स्ट्रक्चर प्रॉपर्टी को असाइन करने का कोई तरीका है?

अभी मैं जो उपाय अपना रहा हूं वह निम्नलिखित है:

type Foo struct {
    More String `json:"more"`
    Foo  struct {
        Bar string `json:"bar"`
        Baz string `json:"baz"`
    } `json:"foo"`
    //  FooBar  string `json:"foo.bar"`
}

यह एक सरलीकृत संस्करण है, कृपया क्रिया की उपेक्षा करें। जैसा कि आप देख सकते हैं, मैं मूल्य को पार्स और असाइन करने में सक्षम होना चाहता हूं

//  FooBar  string `json:"foo.bar"`

मैंने लोगों को एक मानचित्र का उपयोग करते देखा है, लेकिन यह मेरा मामला नहीं है। मैं मूल रूप से fooकुछ विशिष्ट तत्वों को छोड़कर (जो कि एक बड़ी वस्तु है) की सामग्री की परवाह नहीं करता।

इस मामले में सही दृष्टिकोण क्या है? मैं अजीब हैक की तलाश नहीं कर रहा हूं, इस प्रकार अगर यह जाने का रास्ता है, तो मैं इसके साथ ठीक हूं।

जवाबों:


67

क्या नेस्टेड बार प्रॉपर्टी को अनमार्टस करने और नेस्टेड स्ट्रक्चर बनाए बिना इसे सीधे किसी स्ट्रक्चर प्रॉपर्टी को असाइन करने का कोई तरीका है?

नहीं, एन्कोडिंग / json "> कुछ> गहरे> चाइल्डनोड" के साथ ट्रिकिंग नहीं कर सकता जैसे एन्कोडिंग / xml कर सकता है। नेस्टेड स्ट्रक्चर्स जाने का रास्ता है।


1
यह एन्कोडिंग / xml से अलग क्यों है?
कालेब चूल्हा

1
@CalebThompson XML और JSON के लिए संरचना पूरी तरह से अलग है, भले ही साधारण मामले एक जैसे दिखते हों। XML टैग की सामग्री थोड़े है: (उप-टैग या पाठ का एक आदेशित नक्शा) और विशेषताओं का एक अनियंत्रित नक्शा। JSON बहुत कुछ गो संरचना की तरह है। इसलिए JSON को स्ट्रक्चर्स की मैपिंग करना बहुत सरल है: अपने JSON के बाद केवल स्ट्रक्चर को मॉडल करें।
वोल्कर

मेरे मामले में JSON की संरचना वास्तव में तय नहीं की गई है इसलिए मैं एक संरचना बना सकता हूं और जब मैं इसे [string] इंटरफ़ेस {} के मानचित्र का उपयोग करके पार्स करता हूं, तो मुझे नेस्टेड तत्वों के लिए समस्या हो रही है। क्या किया जा सकता है।?
viveksinghggits

लेकिन हम संरचना के अंदर संरचना करने के लिए क्यों नहीं कर सकते?
विटाली ज़डनेविच

29

जैसा कि वोल्कर ने उल्लेख किया है, नेस्टेड संरचनाएं जाने का रास्ता है। लेकिन अगर आप वास्तव में नेस्टेड संरचना नहीं चाहते हैं, तो आप अनमरशालसन फन को ओवरराइड कर सकते हैं।

https://play.golang.org/p/dqn5UdqFfJt

type A struct {
    FooBar string // takes foo.bar
    FooBaz string // takes foo.baz
    More   string 
}

func (a *A) UnmarshalJSON(b []byte) error {

    var f interface{}
    json.Unmarshal(b, &f)

    m := f.(map[string]interface{})

    foomap := m["foo"]
    v := foomap.(map[string]interface{})

    a.FooBar = v["bar"].(string)
    a.FooBaz = v["baz"].(string)
    a.More = m["more"].(string)

    return nil
}

कृपया इस तथ्य को अनदेखा करें कि मैं एक उचित त्रुटि नहीं लौटा रहा हूं। मैंने उसे सरलता के लिए छोड़ दिया।

अद्यतन: "अधिक" मान को सही ढंग से पुनर्प्राप्त कर रहा है।


3
मुझे मिल रहा है और {FooBar: 1 FooBaz: 2 More:}। "पाठ" गायब है
गाय सेगेव

@GuySegev मैंने आगे बढ़कर उस मुद्दे को ठीक करने के लिए अपना उत्तर अपडेट किया। यह बात बताने के लिए धन्यवाद।
रेक्सपोसैडस

22

यह एक उदाहरण है कि Safebrowsing v4 API sbserver प्रॉक्सी सर्वर से JSON की प्रतिक्रियाओं को कैसे अनमोल करें: https://play.golang.org/p/4rGB5da0Lt

// this example shows how to unmarshall JSON requests from the Safebrowsing v4 sbserver
package main

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

// response from sbserver POST request
type Results struct {
    Matches []Match     
}

// nested within sbserver response
type Match struct {
    ThreatType string 
    PlatformType string 
    ThreatEntryType string 
    Threat struct {
        URL string
    }
}

func main() {
    fmt.Println("Hello, playground")

    // sample POST request
    //   curl -X POST -H 'Content-Type: application/json' 
    // -d '{"threatInfo": {"threatEntries": [{"url": "http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"}]}}' 
    // http://127.0.0.1:8080/v4/threatMatches:find

    // sample JSON response
    jsonResponse := `{"matches":[{"threatType":"MALWARE","platformType":"ANY_PLATFORM","threatEntryType":"URL","threat":{"url":"http://testsafebrowsing.appspot.com/apiv4/ANY_PLATFORM/MALWARE/URL/"}}]}`

    res := &Results{}
    err := json.Unmarshal([]byte(jsonResponse), res)
        if(err!=nil) {
            log.Fatal(err)
        }

    fmt.Printf("%v\n",res)
    fmt.Printf("\tThreat Type: %s\n",res.Matches[0].ThreatType)
    fmt.Printf("\tPlatform Type: %s\n",res.Matches[0].PlatformType)
    fmt.Printf("\tThreat Entry Type: %s\n",res.Matches[0].ThreatEntryType)
    fmt.Printf("\tURL: %s\n",res.Matches[0].Threat.URL)
}

2
यह दिखाने के लिए धन्यवाद कि json.Unmarshal एक जटिल गहराई से नेस्टेड json डेटा को अनमर्श कर सकता है । मेरी समस्या यह थी कि मैं एक फाइल से JSON पढ़ रहा था और कुछ शून्य पैडिंग के साथ समाप्त हुआ। खुशी है कि आपने इसे साझा किया!
रोहतेविज़

12

हाँ। Gjson के साथ अब आपको बस इतना करना है:

bar := gjson.Get(json, "foo.bar")

barयदि आप चाहें तो एक संरचनागत संपत्ति हो सकती है। इसके अलावा, कोई नक्शे नहीं।


1
Fastjson भी इसी चाल की अनुमति देता है: fastjson.GetString(json, "foo", "bar")
Valyala

9

अनाम क्षेत्रों के बारे में क्या? मुझे यकीन नहीं है कि अगर यह "नेस्टेड स्ट्रक्चर" होगा, लेकिन यह नेस्टेड स्ट्रक्चर डिक्लेरेशन होने की तुलना में क्लीनर है। क्या होगा यदि आप नेस्टेड तत्व को कहीं और फिर से उपयोग करना चाहते हैं?

type NestedElement struct{
    someNumber int `json:"number"`
    someString string `json:"string"`
}

type BaseElement struct {
    NestedElement `json:"bar"`
}

1

jsonजब तक आप अंतर्निहित प्रकार की json कुंजियाँ नहीं जानते, तब तक नेस्टेड टू नेस्टेड के मूल्यों को असाइन करें : -

package main

import (
    "encoding/json"
    "fmt"
)

// Object
type Object struct {
    Foo map[string]map[string]string `json:"foo"`
    More string `json:"more"`
}

func main(){
    someJSONString := []byte(`{"foo":{ "bar": "1", "baz": "2" }, "more": "text"}`)
    var obj Object
    err := json.Unmarshal(someJSONString, &obj)
    if err != nil{
        fmt.Println(err)
    }
    fmt.Println("jsonObj", obj)
}

0

मैं कुछ इस तरह से काम कर रहा था। लेकिन केवल प्रोटो से उत्पन्न संरचनाओं के साथ काम कर रहा है। https://github.com/flowup-labs/grpc-utils

आपके प्रोटो में

message Msg {
  Firstname string = 1 [(gogoproto.jsontag) = "name.firstname"];
  PseudoFirstname string = 2 [(gogoproto.jsontag) = "lastname"];
  EmbedMsg = 3  [(gogoproto.nullable) = false, (gogoproto.embed) = true];
  Lastname string = 4 [(gogoproto.jsontag) = "name.lastname"];
  Inside string  = 5 [(gogoproto.jsontag) = "name.inside.a.b.c"];
}

message EmbedMsg{
   Opt1 string = 1 [(gogoproto.jsontag) = "opt1"];
}

तब आपका आउटपुट होगा

{
"lastname": "Three",
"name": {
    "firstname": "One",
    "inside": {
        "a": {
            "b": {
                "c": "goo"
            }
        }
    },
    "lastname": "Two"
},
"opt1": "var"
}

2
यह बताने के लिए कुछ पंक्तियाँ जोड़ें कि यह कैसे प्रश्न का उत्तर देती है। यदि रेपो हटा दिया जाता है तो उत्तर में कोई मूल्य नहीं बचा है।
Ubercool

मुझे नहीं लगता कि वह वापस आ रहा है, साथी।
देवएक्स

-1

मानचित्र और संरचना के संयोजन से JSON ऑब्जेक्ट्स को अनमैर्श करने की अनुमति मिलती है जहां कुंजी गतिशील है। => नक्शा [स्ट्रिंग]

उदाहरण के लिए: stock.json

{
  "MU": {
    "symbol": "MU",
    "title": "micro semiconductor",
    "share": 400,
    "purchase_price": 60.5,
    "target_price": 70
  },
  "LSCC":{
    "symbol": "LSCC",
    "title": "lattice semiconductor",
    "share": 200,
    "purchase_price": 20,
    "target_price": 30
  }
}

आवेदन जाओ

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "os"
)

type Stock struct {
    Symbol        string  `json:"symbol"`
    Title         string  `json:"title"`
    Share         int     `json:"share"`
    PurchasePrice float64 `json:"purchase_price"`
    TargetPrice   float64 `json:"target_price"`
}
type Account map[string]Stock

func main() {
    raw, err := ioutil.ReadFile("stock.json")
    if err != nil {
        fmt.Println(err.Error())
        os.Exit(1)
    }
    var account Account
    log.Println(account)
}

हैश में गतिशील कुंजी एक स्ट्रिंग है, और नेस्टेड ऑब्जेक्ट को एक संरचना द्वारा दर्शाया गया है।


3
यह अधूरा लगता है। कच्चे अप्रयुक्त है
buildmaestro
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.