2016-12-01 1 views
0

Ich habe eine Funktion, die JSON zurückgibt, und der Rückgabetyp ist dies:Extrahierung Elemente aus JSON

map[string]interface{} 

In meinem speziellen Fall, ich weiß, dass das zurückgegebene JSON wie folgt aussieht:

{ 
    "someNumber": 1, 
    "someString": "ee", 
    "someArray": [ 
    "stringInArray", 
    { 
     "anotherNumber": 100, 
     "anotherString": "asdf", 
     "yetAnotherString": "qwer" 
    } 
    ] 
} 

Ich möchte den Wert von "stringInArray" und auch "anotherString" erhalten. Ich habe beispielsweise nach Lösungen gesucht von Go by Example und blog.golang.org, aber ich war nicht erfolgreich.

Zum Beispiel, da res die json aus dem Funktionsaufruf zurückgegeben werden, habe ich versucht, diese (von unterwegs Blog):

var f interface{} 
b := []byte(`res`) 
err2 := json.Unmarshal(b, &f) 
if err2!=nil{ 
    log.Fatalf("Err unmarshalling: %v", err2) 
} 

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

for k, v := range m { 
    switch vv := v.(type) { 
    case string: 
     fmt.Println(k, "is string", vv) 
    case int: 
     fmt.Println(k, "is int", vv) 
    case []interface{}: 
     fmt.Println(k, "is an array:") 
     for i, u := range vv { 
      fmt.Println(i, u) 
     } 
    default: 
     fmt.Println(k, "is of a type I don't know how to handle") 
    } 
} 

(Ich weiß, dass die oben nicht genau tun würde, was ich will aber es ist ein Anfang) aber wenn die Ausführung von Code trifft b. = [] Byte (res), bekomme ich diesen Fehler:

Err unmarshalling: invalid character 'r' looking for beginning of value 

Was ist der effizienteste Methode/Best Practice um die Werte zu erhalten? Ich bin offen für jede Lösung, nicht unbedingt für die obige Vorgehensweise.

@sydnash Hier ist der Code, den ich in meiner Antwort auf deinen Kommentar versprochen:

type LoginResponse2 struct { 

    id float64 
    jsonrpc string 
    result struct { 
     token string 
     details struct { 
      a float64 
      b string 
      c float64 
     } 
    } 
} 

var resStruct2 LoginResponse2 
// Convert result to json 
b, _ :=json.Marshal(res) 
fmt.Println(string(b)) 
// results of Println: 
{"id":1,"jsonrpc":"2.0","result":[ "myToken",{"a":someNumber,"b":"some string","c":someOtherNumber} ] } 


// Unmarshall json into struct 
err2 := json.Unmarshal(b, &resStruct2) 
if err2 != nil { 
    log.Fatalf("Error unmarshalling json: %v", err) 
} 

fmt.Println("Here is json unmarshalled into a struct") 
fmt.Println(resStruct2) 
// results of Println 
{0 { {0 0}}} 
+2

Die Zeichenfolge '" res "' ist nicht gültig json, so dass Sie nicht davon abmaren können. – JimB

Antwort

1

Ich denke, Sie sollten verwenden b: = [] Byte (res) stattdessen b: = [] Byte [res] und Res sollte ein JSON-String oder [] Byte sein. res ist kein legales JSON-Format.

diese Informationen, die Ihnen vielleicht helfen: Um Abstellungs JSON in einen Schnittstellenwert, Abstellungs speichert eine davon in dem Schnittstellenwert:

Bool, für JSON booleans

float64, für JSON Zahlen

Zeichenfolge, für JSON-Strings

[] Schnittstelle {}, für JSON-Arrays

map [string] Schnittstelle {}, für JSON-Objekte

nil für JSON null

können Sie sehen, gibt es keine int aber float64 für JSON-Nummern.

+0

Danke, sydnash. Das erste Problem, das ich lösen muss, ist dies: ** res ** ist ** map [string] Schnittstelle {} ** und nicht gültig json. Wie konvertiere ich nach json? –

+0

Durch einen sehr ausführlichen Prozess des Iterierens über das 'res'-Objekt konnte ich Werte extrahieren und eine Struktur auffüllen (was ich basierend auf @ miltonbs Antwort über das Unmarshalling von json in die Struktur tun möchte), aber ich habe ein Gefühl dass ich nur dupliziere, was die 'json.Unmarshall' Funktion tut. Ich wäre also immer noch daran interessiert zu wissen, ob es eine ziemlich saubere, direkte Möglichkeit gibt, die 'map [string] Schnittstelle {}' nach json zu konvertieren. Vielen Dank. –

+0

Sie meinen, Sie möchten Karte in Json konvertieren? Wenn der Werttyp für alle Elemente integriert ist, kann Ihnen dieses Beispiel helfen. https://play.golang.org/p/rpy1Txz6wK – sydnash

1

Es ist ein Beispiel dafür, wie json in der Dokumentation auf golang Pakete entpacken encoding/json. Im Wesentlichen ist Ihr Problem, dass der Unmarschall erwartet, den JSON in type zu setzen. Daher muss Ihr Code einen Typ deklarieren, der die json darstellt, aus der Sie konvertieren.

Beispiel des json und dem deklarierten Typ aus dem verknüpften Beispiel:

var jsonBlob = []byte(`[ 
    {"Name": "Platypus", "Order": "Monotremata"}, 
    {"Name": "Quoll", "Order": "Dasyuromorphia"} 
]`) 
type Animal struct { 
    Name string 
    Order string 
} 

Einmal definieren Sie die Art es fallen alle in Ort sollte.

+1

Danke, miltonb. Wenn ich Sie richtig verstehe, muss ich eine Struktur erstellen, die den JSON darstellt –

+0

Ja das ist richtig. – miltonb

+1

Sie können auch die Bibliothek [mapstructure] (https://github.com/mitchellh/mapstructure) verwenden, wenn sich das Schema Ihrer Eingabe-JSON auf unvorhersehbare Weise ändert. –