2016-05-11 37 views
0

我正在通過使用Go和Yahoo API構建股票報價Web應用程序。在golang json.Unmarshal中處理單個或數組結構的好方法是什麼?

問題是如何在不寫另一個結構的情況下在數組和單個結構之間切換。我不知道如何用文字解釋。 這裏是例子:

獲取一個符號報價從雅虎API看起來是這樣的:

{"query":{"count":1,"created":"2016-05-11T02:12:33Z","lang":"en-US","results":{"quote":{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"}}}} 

獲取從雅虎API多個報價:

{"query":{"count":2,"created":"2016-05-11T02:17:48Z","lang":"en-us","results":{"quote":[{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"},{"Change":"+0.63","DaysLow":"92.11","DaysHigh":"93.57","Name":"Apple Inc.","Open":"93.35","PreviousClose":"92.79","Symbol":"aapl","Volume":"33686836","PercentChange":"+0.68%"}]}}} 

的差報價成爲一個數組[]

使用json.Unmarshal(quoteResultRawJSON, &queryResult)時如何處理?

我已經結構是這樣的:

type QueryResult struct { 
    Id bson.ObjectId `bson:"_id,omitempty"` 
    Query Query `json:"query"` 
} 

type Query struct { 
    Count int `json:"count"` 
    Created string `json:"created"` 
    Lang string `json:"lang"` 
    Results Quote `json:"results"` 
} 

type Quote struct { 
    Quote StockQuote `json:"quote"` //Here is the difference. Do I need to re-write the whole struct in order to handle [] 
} 

type StockQuote struct { 
    Change string `json:"change"` 
    PercentChange string `json:"percentChange"` 
    DaysLow string `json:"daysLow"` 
    DaysHigh string `json:"daysHigh"` 
    Open string `json:"open"` 
    PreviousClose string `json:"previousClose"` 
    Symbol string `json:"symbol"` 
    Name string `json:"name"` 
    Volume string `json:"volume"` 
} 

我必須寫另一個結構來處理數組?

回答

-1

控制取消編組過程與UnmarshalJSON()重寫。

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

package main 

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

const(
    s1=`{"query":{"count":1,"created":"2016-05-11T02:12:33Z","lang":"en-US","results":{"quote":{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"}}}}` 
    s2=`{"query":{"count":2,"created":"2016-05-11T02:17:48Z","lang":"en-us","results":{"quote":[{"Change":"+0.21","DaysLow":"9.32","DaysHigh":"9.68","Name":"Alcoa Inc. Common Stock","Open":"9.56","PreviousClose":"9.46","Symbol":"aa","Volume":"22266533","PercentChange":"+2.22%"},{"Change":"+0.63","DaysLow":"92.11","DaysHigh":"93.57","Name":"Apple Inc.","Open":"93.35","PreviousClose":"92.79","Symbol":"aapl","Volume":"33686836","PercentChange":"+0.68%"}]}}}` 
) 
type QueryResult struct { 
    //Id bson.ObjectId `bson:"_id,omitempty"` 
    Query Query `json:"query"` 
} 

type Query struct { 
    Count int `json:"count"` 
    Created string `json:"created"` 
    Lang string `json:"lang"` 
    Results Quote `json:"results"` 
} 

type structOrArray struct{ 
    parent *Quote 
    s StockQuote 
    a []StockQuote 
} 

func (this *structOrArray)UnmarshalJSON(data []byte) error{ 
    d := json.NewDecoder(bytes.NewBuffer(data)) 
    t, err := d.Token(); 
    if err != nil{ 
     return err 
    } 
    if t==json.Delim('['){ 
     if err := json.Unmarshal(data, &this.a);err != nil { 
      return err 
     } 
     return nil 
    } 
    if err := json.Unmarshal(data, &this.s);err != nil { 
     return err 
    } 
    return nil 
} 

type fakeQuote struct{ 
    Load structOrArray `json:"quote"` //Here is the difference. Do I need to re-write the whole struct in order to handle [] 
} 
type Quote struct { 
    Quote *StockQuote 
    Quotes []StockQuote 
} 
func (this *Quote)UnmarshalJSON(data []byte) error{ 
    fq := fakeQuote{} 
    if err := json.Unmarshal(data, &fq);err != nil{ 
     return err 
    } 
    this.Quote = &fq.Load.s 
    this.Quotes = fq.Load.a 
    return nil 
} 
type StockQuote struct { 
    Change string `json:"change"` 
    PercentChange string `json:"percentChange"` 
    DaysLow string `json:"daysLow"` 
    DaysHigh string `json:"daysHigh"` 
    Open string `json:"open"` 
    PreviousClose string `json:"previousClose"` 
    Symbol string `json:"symbol"` 
    Name string `json:"name"` 
    Volume string `json:"volume"` 
} 
func main() { 
    r := QueryResult{} 
    err := json.Unmarshal([]byte(s1), &r) 
    if err != nil { 
     log.Fatalln(err) 
    } 
    log.Println(r.Query.Results.Quote) 
    log.Println(r.Query.Results.Quotes) 

    err = json.Unmarshal([]byte(s2), &r) 
    if err != nil { 
     log.Fatalln(err) 
    } 
    log.Println(r.Query.Results.Quote) 
    log.Println(r.Query.Results.Quotes) 
} 
相關問題