post Image
Go言語でのJSONデータの扱い【備忘録】

JSONの処理

JSONを扱う場合encoding/jsonを使う。Goの場合、JSONデータを定義した構造体に入れるのが一般的。

JSONの解析

{
    "id": 1,
    "name": "nana",
    "birthday": "08-16",
    "vivid_info": {
      "color": "red",
      "weapon": "Rang"
    }
}

このようなデータ構造の場合、以下のように構造体を定義する。

type Person struct {
    ID int `json:"id"`
    Name string `json:"name"`
    Birthday string `json:"birthday"`
    VividInfo struct {
        Color string `json:"color"`
        Weapon string `json:"weapon"`
    } `json:"vivid_info"`
}

JSONから構造体のコードを生成してくれるJSON-to-Goを使うと便利。

JSONをデコードするにはjson.Unmarshal関数を使う。

func Unmarshal(data []byte, v interface{}) error

デコードされたデータは以下のようにして扱うことができる。

var persons []Person
for _, p := range persons{
  fmt.Printf("%d : %s : %s : %s : %s\n", p.ID, p.Name, p.Birthday, p.VividInfo.Color, p.VividInfo.Weapon)
}

// 表示結果
// 1 : nana : 08-16 : red : Rang

未知のデータ構造をもつJSONの解析

JSONデータの構造を事前に知らない場合、interfaceを用いて解析する。JSONパッケージではmap[string]interface{}interface{}構造を採用して任意のJSONオブジェクトを保存する。Goの型とJSONの型の対応は以下。

  • boolはJSON booleansを表す。
  • float64はJSON numberを表す。
  • stringはJSON stringを表す。
  • nilはJSON nilを表す。

以下のようなJSONデータがあるとし、この構造を把握していないと仮定する。

b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)

これをinterface{}の中に解析。

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

このときfの中にはmap型が保存されている。これらのkeyはstringで、値は空のinterface{}の中に保存される。

f = map[string]interface{}{
  "Name": "Wednesday",
    "Age":  6,
    "Parents": []interface{}{
        "Gomez",
        "Morticia",
    },
}

これらのデータにアクセスするには以下のようにする。

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 float64:
    fmt.Println(k, "is float64", 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 dont know how to handle")
  }
}

(めんどくさいのでJSONを取得してJSON-to-Goを利用して構造体にぶち込んだほうが見通しが良さそう。)

go-simplejson

上の例よりも簡単にJSONを扱うことのできるパッケージ

go get github.com/bitly/go-simplejson

使い方

下記のjsonを扱う場合、

[simple.json]
{
    "hoge": true,
    "piyo":{
        "foo":[1,2],
        "bar":"test"
    }
}
import( 
  simplejson "go-simplejson"
)

//jsonファイルの読み込み
bytes, err := ioutil.ReadFile("./simple.json")
if err != nil {
  log.Fatal(err)
}

// []byte型からjson型へ変換
json,err := simplejson.NewJson(bytes)

// Get("hoge").Type()またはGet("hoge").MustType()でアクセスできる。
// Type()は値とエラーを返す
b, _ := json.Get("hoge").Bool() // => true
 // MustType()は値のみ
m := json.Get("piyo").MustMap() // => map[bar:test foo:[1 2]]
a, _ := json.Get("piyo").Get("foo").Array()  // => [1,2]
// GetPath()で一括記述
s := js.GetPath("piyo", "bar").MustString() // => test

以下のような、配列で構成されるJSONデータの扱いは

[
  {
    "id": 1,
    "name": "akane",
    "birthday": "08-16",
    "vivid_info": {
      "color": "red",
      "weapon": "Rang"
    }
  },
  {
    "id": 2,
    "name": "aoi",
    "birthday": "06-17",
    "vivid_info": {
      "color": "blue",
      "weapon": "Impact"
    }
  },
  {
    "id": 3,
    "name": "wakaba",
    "birthday": "05-22",
    "vivid_info": {
      "color": "green",
      "weapon": "Blade"
    }
  },
  {
    "id": 4,
    "name": "himawari",
    "birthday": "07-23",
    "vivid_info": {
      "color": "yellow",
      "weapon": "Collider"
    }
  },
  {
    "id": 0,
    "name": "rei"
  }
]

このようにforで回してアクセス。他にもっといい方法あったら教えてください。

for i, _ := range json.MustArray() {
  fmt.Printf("id: %d\n", json.GetIndex(i).Get("id").MustInt())
  fmt.Printf("name: %s\n", json.GetIndex(i).Get("name").MustString())
  fmt.Printf("birthday: %s\n", json.GetIndex(i).Get("birthday").MustString())
  fmt.Printf("vivid_info:color: %s\n", json.GetIndex(i).Get("vivi_info").Get("color").MustString())
  fmt.Printf("vivid_info:weapon: %s\n", json.GetIndex(i).Get("vivi_info").Get("weapon").MustString())
}

rubyに比べると少し面倒な印象。

参考


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。