必要な場面
xmlのデータ上はstring
な公開日時のようなパラメータを、Unmarshalしたらtime.Time
としてあつかいたいとき。
unmarshal_test.go
import(
"testing"
"encoding/xml"
"time"
)
// Item の定義
type Item struct {
Title string `xml:"title"`
Link string `xml:"link"`
PublishedAt time.Time
}
// xml.Unmarshal 時にcallされるメソッドを独自実装
func (item *Item) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// 生XMLを扱うための定義. PublishedAt は string であること
raw := struct {
Title string `xml:"title"`
Link string `xml:"link"`
PublishedAt string `xml:"publishedAt"`
}{}
// デコード
if err := d.DecodeElement(&raw, &start); err != nil {
return err
}
// string to time.Time の変換処理
timePub, err := time.Parse(time.RFC1123Z, raw.PublishedAt)
if err != nil {
return err
}
// Itemを構築して返す
*item = Item {
raw.Title,
raw.Link,
timePub,
}
return nil
}
// テスト
func TestUnmarshalSelf(t *testing.T) {
xmlData := `
<item>
<title>そうだ京都に行こう</title>
<link>http://go-kyoto.com/</link>
<publishedAt>Tue, 15 Mar 2016 11:08:00 +0900</publishedAt>
</item>
`
item := Item{}
err := xml.Unmarshal([]byte(xmlData), &item)
if err != nil{
t.Error("パースに失敗してるよ!")
}
if item.PublishedAt.IsZero() {
t.Error("パースエラーだ!")
}
if item.PublishedAt.Year() != 2016 {
t.Error("パースエラーだ!")
}
}
日付処理については、Big Sky :: Go言語で日付処理が参考になりました。