2016-07-24 7 views
1

JSONというメッセージを受け取るアプリがあります。 JSONにはさまざまな「セクション」(以下の例)があります。各セクションには名前がありますが、それを超える構造はセクションごとに完全に異なります。golangでJSONのサブセクションを解析する

私がしたいことは、セクションを通過し、それぞれを適切なオブジェクトに非整列化することです。しかし、不思議なことに、これは難しいことです。JSON全体をオブジェクトにアンマーシャリングするか、ジェネリックマップ[文字列]インターフェース{}を取得することができます。私が見つけたすべてのサンプルコードは、型の切り替えと手作業での変数の割り当てになります...私はオブジェクトに直接neato Unmarshalを行うことを望んでいました。

JSONのサブセットを非整列化する方法はありますか?私はバイト[]をスライスしてダイスすることができましたが、それは凄いようです...確かに他の人はこのようなことを経験しましたか?

これは私がプレイしたものです。

package main 

import "encoding/json" 

type Book struct { 
    Author string 
    Title string 
    Price float64 
} 

type Movie struct { 
    Title string 
    Year float64 
    Stars float64 
    Format string 
} 

var sections map[string]interface{} 

func main() { 

    /* 
    * "Book" and "Movie" are "sections". 
    * There are dozens of possible section types, 
    * and which are present is not known ahead of time 
    */ 

    incoming_msg_string := ` 
{ 
    "Book" : { 
     "Author" : "Jack Kerouac", 
     "Title" : "On the Road", 
     "Price" : 5.99 
    }, 
    "Movie" : { 
     "Title" : "Sherlock Holmes vs. the Secret Weapon", 
     "Year" : 1940, 
     "Stars" : 2.5, 
     "Format" : "DVD" 
    } 
}` 

    /* 
    * this code gets me a list of sections 
    */ 

    var f interface{} 
    err := json.Unmarshal([]byte(incoming_msg_string), &f) 
    if err != nil { 
     panic(err) 
    } 

    var list_of_sections []string 
    for section_type, _ := range f.(map[string]interface{}) { 
     list_of_sections = append(list_of_sections, section_type) 
    } 

    /* 
     * next I would like to take the JSON in the "book" section 
     * and unmarshal it into a Book object, then take the JSON 
     * in the "movie" section and unmarshal it into a Movie object, 
     * etc. 
     * 
     * https://blog.golang.org/json-and-go has an example on 
     * decoding arbitrary data, but there's only one Unmarshaling. 
     * 
     * json.RawMessage has an example in the docs but it assumes 
     * the objects are the same type (I think). My attempts to use 
     * it with a two-field struct (section name, and a raw message) 
     * gave runtime errors. Likewise unmarshaling into a 
     * []json.RawMessage gave "panic: json: cannot unmarshal object into Go value of type []json.RawMessage" 
     * 
     * What I'm looking for is something like: 
     * json.Unmarshal(some_json["a certain section"],&object) 
     * 
    */ 
} 

ブレッドクラムのトレイルのヒントは非常に高く評価されています。

答えて

2

type Sections map[string]json.RawMessage変数に初期非整列化を行いますか?セクションタイプとそれに関連付けられた生データがあります。セクションのタイプをオンにして、特定のセクション構造体に非マーシャルするか、マップ[文字列]インタフェース{}に対して非整列化してそれらを一般的に処理することができます。 (あなたのアプリに最適なものはどれでも)

+0

ありがとう - それは美しいです。なぜ私は数時間のグーグルと実験がそのシンプルさを明らかにしなかったのか分かりませんが、それは学習の夜でした:-)ありがとうございました。 – raindog308