在Golang中解析JSON,答案为无键数组[关闭]
问题描述:
How to handle json if the response comes with an array of data (in JS it was decided by fetching the necessary data on the index), I saw that I wrote that through Unmarshal into the structure, but I can not save the array in the structure so that I can then take the indices from the keys because there are no keys on which you can create a structure.
package main
import (
"fmt"
"net/http"
)
func main() {
url := "My request"
request := "https://en.wikipedia.org/w/api.php?action=opensearch&search=" + url + "&limit=5&origin=*&format=json"
response, err := http.Get(request)
if err != nil {
fmt.Printf("%s", err)
}
}
Here's what comes in answer
["bee",["Bee","Beer","Bee Gees","Beef","Beetle"],["Bees are flying insects closely related to wasps and ants, known for their role in pollination and, in the case of the best-known bee species, the European honey bee, for producing honey and beeswax.","Beer is one of the oldest and most widely consumed alcoholic drinks in the world, and the third most popular drink overall after water and tea.","The Bee Gees were a pop music group formed in 1958. Their lineup consisted of brothers Barry, Robin, and Maurice Gibb.","Beef is the culinary name for meat from cattle, particularly skeletal muscle. Humans have been eating beef since prehistoric times.","Beetles are a group of insects that form the order Coleoptera, in the superorder Endopterygota. Their front pair of wings is hardened into wing-cases, elytra, distinguishing them from most other insects."],["https://en.wikipedia.org/wiki/Bee","https://en.wikipedia.org/wiki/Beer","https://en.wikipedia.org/wiki/Bee_Gees","https://en.wikipedia.org/wiki/Beef","https://en.wikipedia.org/wiki/Beetle"]]
答
You could define a custom type which implements json.Unmarshaler
by mapping the parsed array values into a struct such as below:
type SearchResults struct {
Query string
Results []Result
}
type Result struct {
Name, Description, URL string
}
func (sr *SearchResults) UnmarshalJSON(bs []byte) error {
array := []interface{}{}
err := json.Unmarshal(bs, &array)
if err != nil {
return err
}
sr.Query = array[0].(string)
for i := range array[1].([]interface{}) {
sr.Results = append(sr.Results, Result{
array[1].([]interface{})[i].(string),
array[2].([]interface{})[i].(string),
array[3].([]interface{})[i].(string),
})
}
return nil
}
func main() {
sr := &SearchResults{}
err := json.Unmarshal([]byte(jsonstr), sr)
if err != nil {
panic(err)
}
fmt.Printf("OK: query=%q
", sr.Query)
for i, result := range sr.Results {
fmt.Printf("OK: result[%d]=%#v
", i, result)
}
}
// OK: query="bee"
// OK: result[0]=main.Result{Name:"Bee", Description:"Bees are flying insects closely related to wasps and ants, known for their role in pollination and, in the case of the best-known bee species, the European honey bee, for producing honey and beeswax.", URL:"https://en.wikipedia.org/wiki/Bee"}
// OK: result[1]=main.Result{Name:"Beer", Description:"Beer is one of the oldest and most widely consumed alcoholic drinks in the world, and the third most popular drink overall after water and tea.", URL:"https://en.wikipedia.org/wiki/Beer"}
// OK: result[2]=main.Result{Name:"Bee Gees", Description:"The Bee Gees were a pop music group formed in 1958. Their lineup consisted of brothers Barry, Robin, and Maurice Gibb.", URL:"https://en.wikipedia.org/wiki/Bee_Gees"}
// OK: result[3]=main.Result{Name:"Beef", Description:"Beef is the culinary name for meat from cattle, particularly skeletal muscle. Humans have been eating beef since prehistoric times.", URL:"https://en.wikipedia.org/wiki/Beef"}
// OK: result[4]=main.Result{Name:"Beetle", Description:"Beetles are a group of insects that form the order Coleoptera, in the superorder Endopterygota. Their front pair of wings is hardened into wing-cases, elytra, distinguishing them from most other insects.", URL:"https://en.wikipedia.org/wiki/Beetle"}
答
Thanks @Peter for answer and code example: https://play.golang.org/p/t-iuGVaRsNM
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
)
func main() {
//Ask user to enter search parameter
fmt.Printf("Search something: ")
var s string
fmt.Scanf("%s", &s)
//Create search url
url := s
request := "https://en.wikipedia.org/w/api.php?action=opensearch&search=" + url + "&limit=5&origin=*&format=json"
//Sending request
response, err := http.Get(request)
if err != nil {
log.Fatal(err)
}
defer response.Body.Close()
//Unmarshal and store to responsedata interface
var responsedata []interface{}
if err := json.NewDecoder(response.Body).Decode(&responsedata); err != nil {
log.Fatal(err)
}
//Loop through the responsedata and output
for _, x := range responsedata {
switch value := x.(type) {
case string:
fmt.Println(value)
case []interface{}:
for _, v := range value {
fmt.Println(v.(string))
}
}
}
}