Golang jsonファイル処理

7705 ワード

JSONは軽級級のデータ交換言語で、文字を基礎にして、自己説明性があり、読みやすいです.JSONはJavascriptのサブセットであるが、JSONは言語と独立したテキスト形式であり、C言語家族のようないくつかの習慣を採用している.JSONとXMLの最大の違いはXMLは完全なマーク言語であり、JSONはそうではない.JSONはXMLより小さく、より速く、より解析しやすく、ブラウザの内部構築による迅速な解析サポートにより、ネットワークデータ転送領域に適用されます.現在私たちは多くのオープンプラットフォームを見ていますが、基本的には彼らのデータインタラクションのインターフェースとしてJSONを採用しています.JSONがWeb開発において重要である以上、Go言語はJSONをサポートするのはいかがですか?Go言語の標準ライブラリはJSONを非常によくサポートしており、JSONデータを簡単に編集・復号することができます.以下のJSONソースファイルを例にとって
{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"},{"serverName":"Guangzhou_VPN","serverIP":"127.0.0.3"}]}
解析JSON
構造体に解析する
  Golangで提供されるソフトウェア・パケット"encoding/json"は、JSONファイルを直接処理するために使用されてもよく、このパケットの中でJSONの関数を解析するのはUnmarshalであり、この関数を使用してJSONファイルを構造体に解析することができる.
func Unmarshal(data []byte, v interface{}) error
以下のコードを参照してください
package main

import (
    "encoding/json"
    "fmt"
)

type Server struct {
    ServerName string
    ServerIP   string
}

type Serverslice struct {
    Servers []Server
}

func main() {
    var s Serverslice
    str := `{"servers":[{"serverName":"Shanghai_VPN","serverIP":"127.0.0.1"},{"serverName":"Beijing_VPN","serverIP":"127.0.0.2"},{"serverName":"Guangzhou_VPN","serverIP":"127.0.0.3"}]}`
    json.Unmarshal([]byte(str), &s)
    fmt.Println(s)
}
上記コードの出力は
{[{Shanghai_VPN 127.0.0.1} {Beijing_VPN 127.0.0.2} {Guangzhou_VPN 127.0.0.3}]}
上記の例では、まずjsonデータに対応する構造体を定義しました.配列はsliceに対応しています.フィールド名はJSONのKEYに対応しています.解析する時、どのようにjsonデータをstructフィールドにマッチングさせますか?例えばJSONのキーはFooですが、どのように対応するフィールドを探しますか?
  • は、まず、(Fooを含む導き出すことができるstructフィールド(イニシャル大文字)
  • を検索する.
  • 、次いで検索フィールド名はFooの導出フィールド
  • である.
  • 最後に、FOOまたはFoOのような、最初の文字以外の大きさの書き込みに敏感でない導出フィールドを検索します.ここで注意すべき点は、値が割り当てられるフィールドは導出可能なフィールドでなければなりません.(頭文字が大文字)JSON解析の際に見つけられるフィールドだけが解析されます.見つけられないフィールドは無視されます.大きなJSONデータ構造を受信しても一部のデータだけを取得したい場合、あなたが欲しいデータに対応するフィールド名を大文字にするだけで簡単に解決できるという利点があります.
  • インターフェースに解析
    上記の解析方式は、解析されたJSONデータの構造を知ることを前提としたスキームであり、解析されたデータのフォーマットが分からない場合、どのように解析すればいいですか?Golangでは、interface{}は、解析された未知の構造のjsonデータを格納するために用いられます.ONパケットには、任意のJSONオブジェクトと配列をmap[string]interface{}[]interface{}構造で記憶しています.GoタイプとJSONタイプの対応関係は以下の通りです.
  • bookはJSON bollansを代表して、
  • float 64はJSON numbersを代表して、
  • stringはJSON strigsを代表して、
  • nilはJSON nullを表します.以下のようなJSONデータ
  • があると仮定します.
    b := []byte(`{"Name":"Wednesday","Age":6,"Parents":["Gomez","Morticia"]}`)
    
    知らないJSONの構造の下で、彼をinterface{}の中に解析します.
    var f interface{}
    err := json.Unmarshal(b, &f)
    
    上記コードの実行結果はfmapタイプが格納されており、keystringであり、値はinterface{}に記憶されている.
    f = map[string]interface{}{
        "Name": "Wednesday",
        "Age":  6,
        "Parents": []interface{}{
            "Gomez",
            "Morticia",
        },
    }
    
    断言によってinterface{}中のデータにアクセスすることができる.
    m := f.(map[string]interface{})
    
    encoding/jsonパケットでは、以下のように解析します.
    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 don't know how to handle")
        }
    }
    
       実は多くの場合、タイプを使って異常に煩雑で、操作が非常に不便であると断言しています.現在、bitlyはsimplejsonというカバンをソースにしています.未知の構造体のJSONを処理する時に、とても便利です.詳細な例は以下の通りです.
    js, err := NewJson([]byte(`{
        "test": {
            "array": [1, "2", 3],
            "int": 10,
            "float": 5.150,
            "bignum": 9223372036854775807,
            "string": "simplejson",
            "bool": true
        }
    }`))
    
    arr, _ := js.Get("test").Get("array").Array()
    i, _ := js.Get("test").Get("int").Int()
    ms := js.Get("test").Get("string").MustString()
    
    このライブラリを使ってJSONを操作するのは公式のencoding/jsonバッグよりずっと便利です.詳細は下記の住所を参照してください.https://github.com/bitly/go-simplejson
    JSONを生成する
      はJSONの新聞文を解析するのとは対照的に、encoding/jsonパケット提供関数MarshalはJSON文字列を包装し、生成するために提供されています.この関数の定義は以下の通りです.
    func Marshal(v interface{}) ([]byte, error)
    
    以下のコードを参照してください
    package main
    
    import (
        "encoding/json"
        "fmt"
    )
    
    type Server struct {
        ServerName string
        ServerIP   string
    }
    
    type Serverslice struct {
        Servers []Server
    }
    
    func main() {
        var s Serverslice
        s.Servers = append(s.Servers, Server{ServerName: "Shanghai_VPN", ServerIP: "127.0.0.1"})
        s.Servers = append(s.Servers, Server{ServerName: "Beijing_VPN", ServerIP: "127.0.0.2"})
        s.Servers = append(s.Servers, Server{ServerName: "Guangzhou_VPN", ServerIP: "127.0.0.3"})
        
        b, err := json.Marshal(s)
        if err != nil {
            fmt.Println("json err:", err)
        }
        fmt.Println(string(b))
    }
    
    上記コードの出力は
    {"Servers":[{"ServerName":"Shanghai_VPN","ServerIP":"127.0.0.1"},{"ServerName":"Beijing_VPN","ServerIP":"127.0.0.2"}, {"ServerName":"Guangzhou_VPN", "ServerIP":"127.0.0.3"}]}
    
    上記の出力フィールド名の頭文字はすべて大文字です.小文字でどうすればいいですか?構造体のフィールド名を頭文字小文字に変えます.JSON出力時は注意しなければいけません.エクスポートするフィールドだけが出力されます.フィールド名を修正すると何も出力されないので、structで定義しなければなりません.実装:
    type Server struct {
        ServerName string `json:"serverName"`
        ServerIP   string `json:"serverIP"`
    }
    
    type Serverslice struct {
        Servers []Server `json:"servers"`
    }
    
    上記の構造体の定義を修正することにより、出力のJSON列は最初に定義されたJSON列と一致しています.JSONの出力に対しては、struct(struct)を定義する際に以下のような内容が必要です.
  • フィールドの「-」は、JSON
  • に出力されません.
  • (カスタム名を持つ)では、このカスタム名はJSONのフィールド名に現れます.例えば、上記の例ではserverName
  • の中に「omitemipty」のオプションがあると、このフィールドの値が空の場合、JSONの列
  • に出力されません.
  • フィールドタイプがbook、string、int、int 64などの場合、「string」オプションが含まれている場合、このフィールドはJSONに出力する時、このフィールドの対応する値をJSON文字列例えば
  • に変換します.
    type Server struct {
        // ID      JSON 
        ID int `json:"-"`
    
        // ServerName2        JSON  
        ServerName  string `json:"serverName"`
        ServerName2 string `json:"serverName2,string"`
    
        //    ServerIP   ,     JSON  
        ServerIP   string `json:"serverIP,omitempty"`
    }
    
    s := Server {
        ID:         3,
        ServerName:  `Go "1.0" `,
        ServerName2: `Go "1.0" `,
        ServerIP:   ``,
    }
    b, _ := json.Marshal(s)
    os.Stdout.Write(b)
    
    出力内容は以下の通りです.
    {"serverName":"Go \"1.0\" ","serverName2":"\"Go \\\"1.0\\\" \""}
    
    Masharl関数は変換が成功した時だけデータに戻ります.変換の過程では次の点に注意してください.
  • JSONオブジェクトは、stringだけをkeyとしてサポートしているので、mapを符号化するには、map[string]Tのようなタイプ(TはGo言語で任意のタイプ)
  • でなければならない.
  • Chanel、complexとfunctionはJSONにエンコードされない
  • です.
  • ネストされたデータはエンコードできません.そうでないとJSONコードをデッドサイクル
  • に入れます.
  • ポインタは、符号化時にポインタが指す内容を出力し、空のポインタはnull
  • を出力する.
    参考文献
    7.2 JSON処理