uokadaの見逃し三振は嫌いです

ここで述べられていることは私の個人的な意見に基づくものであり、私が所属する組織には一切の関係はありません。

Go言語でXMLのパースする

前にも書いたけどもう一回書いてみる。

Go言語でXMLのパースしたった - uokadaの見逃し三振は嫌いです

前回のは素直なXMLファイルをパースしたので今回は少し実践的なところ。 crossdomain.xmlを取得してパースするサンプルコード。 XMLのタグと構造体の名前が一致しない場合やattributeの取り方などのやりかた。

package main

import (
    "encoding/xml"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "os"
)

type AllowAccessFrom struct {
    // attributeを取るときは"属性,attr"の形式で取得できる        
    Domain string `xml:"domain,attr"`
    Secure bool   `xml:secure,attr`
}

type SiteControl struct {
    // これも上と同じ
    Pemission string `xml:"permitted-cross-domain-policies,attr"`
}

type CrossDomainPolicy struct {
    // タグとフィールドが一致しない場合は `xml:タグ名` で取得
    Policies   SiteControl       `xml:"site-control"`
    DomainList []AllowAccessFrom `xml:"allow-access-from"`
}

// 引数で渡したドメインのcrossdomain.xmlを取得
func get_crossdomain_xml(domain string) []byte {
    entry_point := fmt.Sprintf("http://%s/crossdomain.xml", domain)
    api_data, err := http.Get(entry_point)
    if err != nil {
        log.Fatal("faile HTTP Request")
        log.Fatal(err)
        os.Exit(1)
    }

    x, _ := ioutil.ReadAll(api_data.Body)
    defer api_data.Body.Close()
    if err != nil {
        log.Fatal(err)
    }
    return x
}

func main() {
    // 初期化
    v := CrossDomainPolicy{DomainList: nil}

    data := get_crossdomain_xml("facebook.com")
    fmt.Printf("%#V\n", string(data))

    xerr := xml.Unmarshal(data, &v)
    if xerr != nil {
        fmt.Printf("error: %v", xerr)
        return
    }

    fmt.Printf("%T\n", v)
    fmt.Printf("%+v\n", v)
    for _, domain := range v.DomainList {
        fmt.Printf("%s\n", domain.Domain)
    }
    fmt.Printf("%s\n", v.Policies.Pemission)
    os.Exit(0)
}

基礎からわかる Go言語

基礎からわかる Go言語