Go言語 – 17.XMLのパース ②

2019-08-01Go言語

XMLの生成

XMLのパース ① で作成した構造体を元に、今回はパースとは逆に構造体を元にしてXMLを生成します。

生成

前回のパースの結果です。

前回のパースにより、dataにはこのように要素の値が取得できました。

data.Families[0].Lastname               "山田"
data.Families[0].Members[0].Firstname   "太郎"
data.Families[0].Members[0].Mail        "taro.yamada@aaa.bbb.cc"
data.Families[0].Members[1].Firstname   "花子"
data.Families[0].Members[1].Mail        "hanako.yamada@aaa.bbb.cc"
data.Families[1].Lastname               "花形"
data.Families[1].Members[0].Firstname   "みつる"
data.Families[1].Members[0].Mail        "mitsuru.hanagata@aaa.bbb.cc"
data.Families[1].Members[1].Firstname   "かほる"
data.Families[1].Members[1].Mail        "kahoru.hanagata@aaa.bbb.cc"

前回と同じですが構造体です。

type Data struct {
    Families []Family `xml:"family"`
}

type Family struct {
    Lastname string `xml:"lastname,attr"`
    Members []Members `xml:"member"`
}

type Members struct {
    Firstname string `xml:"firstname"`
    Mail string `xml:"mail"`
}

XML生成部分です。

MarshalIndentにて「data」を元にして「xmlOut」にXMLを生成します。

    // XML生成
    xmlOut, err := xml.MarshalIndent(&data, "", "    ")
    if err != nil {
        fmt.Println("XML Marshal error:", err)
        return
    }

表示箇所です。

    // 生成できたXMLを表示
    fmt.Println(string(xmlOut))

今回のソース全体です。

前回のソースの最後の方に、XML生成部分と表示箇所を追記しているだけのソースです。

package main

import (
    "encoding/xml"
    "fmt"
)

type Data struct {
    Families []Family `xml:"family"`
}

type Family struct {
    Lastname string `xml:"lastname,attr"`
    Members []Members `xml:"member"`
}

type Members struct {
    Firstname string `xml:"firstname"`
    Mail string `xml:"mail"`
}

func main() {
    xmlStr := `
<?xml version="1.0" encoding="UTF-8"?>
<data>
    <family lastname="山田">
        <member>
            <firstname>太郎</firstname>
            <mail>taro.yamada@aaa.bbb.cc</mail>
        </member>
        <member>
            <firstname>花子</firstname>
            <mail>hanako.yamada@aaa.bbb.cc</mail>
        </member>
    </family>
    <family lastname="花形">
        <member>
            <firstname>みつる</firstname>
            <mail>mitsuru.hanagata@aaa.bbb.cc</mail>
        </member>
        <member>
            <firstname>かほる</firstname>
            <mail>kahoru.hanagata@aaa.bbb.cc</mail>
        </member>
    </family>
</data>
`

data := new(Data)
    if err := xml.Unmarshal([]byte(xmlStr), data); err != nil {
        fmt.Println("XML Unmarshal error:", err)
        return
    }

    // 家族1
    fmt.Println(data.Families[0].Lastname)              // 苗字
    fmt.Println(data.Families[0].Members[0].Firstname)  // 名前1
    fmt.Println(data.Families[0].Members[0].Mail)       // メールアドレス1
    fmt.Println(data.Families[0].Members[1].Firstname)  // 名前2
    fmt.Println(data.Families[0].Members[1].Mail)       // メールアドレス2

    // 区切り
    fmt.Println("")

    // 家族2
    fmt.Println(data.Families[1].Lastname)              // 苗字
    fmt.Println(data.Families[1].Members[0].Firstname)  // 名前1
    fmt.Println(data.Families[1].Members[0].Mail)       // メールアドレス1
    fmt.Println(data.Families[1].Members[1].Firstname)  // 名前2
    fmt.Println(data.Families[1].Members[1].Mail)       // メールアドレス2

    // 区切り
    fmt.Println("")

    // XML生成
    xmlOut, err := xml.MarshalIndent(&amp;data, "", "    ")
    if err != nil {
        fmt.Println("XML Marshal error:", err)
        return
    }

    // 生成できたXMLを表示
    fmt.Println(string(xmlOut))

}

実行結果

山田
太郎
tao.yamada@aaa.bbb.cc
花子
hanako.yamada@aaa.bbb.cc

花形
みつる
mitsuru.hanagata@aaa.bbb.cc
かほる
kahoru.hanagata@aaa.bbb.cc

<Data>
    <family lastname="山田">
        <member>
            <firstname>太郎</firstname>
            <mail>taro.yamada@aaa.bbb.cc</mail>
        </member>
        <member>
            <firstname>花子</firstname>
            <mail>hanako.yamada@aaa.bbb.cc</mail>
        </member>
    </family>
    <family lastname="花形">
        <member>
            <firstname>みつる</firstname>
            <mail>mitsuru.hanagata@aaa.bbb.cc</mail>
        </member>
        <member>
            <firstname>かほる</firstname>
            <mail>kahoru.hanagata@aaa.bbb.cc</mail>
        </member>
    </family>
</Data>