xmlからGo strcutを生成する

ツール紹介です。 Web APIのレスポンスはだいたいjsonで返ってくるので、go structを自動生成してくれる JSON-to-Goが便利でよく使っているのですが、今回はxmlで同じことをしたいと思い、chidleyというツールを触ってみたので、使い方をまとめます。

インストール

いつものごとく、go getしましょう。

# go get github.com/gnewton/chidley

使い方

READMEにもありますが、同じサンプル(test.xmlとします)を借ります。

<people>

  <person>
    <name>bill</name>
    <age>37</age>
    <married>true</married>
  </person>

  <person>
    <name>sarah</name>
    <age>24</age>
    <married>false</married>
  </person>

</people>

-Gオプションを付けることでxmlからGo structが生成されます。

# chidley -G test.xml

type ChiChidleyRoot314159 struct {
    ChiPeople *ChiPeople `xml:" people,omitempty" json:"people,omitempty"`
}

type ChiAge struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiMarried struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiName struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiPeople struct {
    ChiPerson []*ChiPerson `xml:" person,omitempty" json:"person,omitempty"`
}

type ChiPerson struct {
    ChiAge *ChiAge `xml:" age,omitempty" json:"age,omitempty"`
    ChiMarried *ChiMarried `xml:" married,omitempty" json:"married,omitempty"`
    ChiName *ChiName `xml:" name,omitempty" json:"name,omitempty"`
}

型付きでコンバート

上記のようにデフォルトではint型やbool型もすべてstring型として解釈されます。-tオプションで型まで含めたコンバートを行ってくれます。

# chidley -G -t test.xml

type ChiChidleyRoot314159 struct {
    ChiPeople *ChiPeople `xml:" people,omitempty" json:"people,omitempty"`
}

type ChiAge struct {
    Text int8 `xml:",chardata" json:",omitempty"`
}

type ChiMarried struct {
    Text bool `xml:",chardata" json:",omitempty"`
}

type ChiName struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type ChiPeople struct {
    ChiPerson []*ChiPerson `xml:" person,omitempty" json:"person,omitempty"`
}

type ChiPerson struct {
    ChiAge *ChiAge `xml:" age,omitempty" json:"age,omitempty"`
    ChiMarried *ChiMarried `xml:" married,omitempty" json:"married,omitempty"`
    ChiName *ChiName `xml:" name,omitempty" json:"name,omitempty"`
}

age24,37int8型として解釈されていますが、chidleyでは以下のように記載されているとおり、できるだけ小さい型に合わせようとします。 今回は-128127の範囲に収まっているために、int8型となります。

chidley tries to fit the smallest Go type. For example, if all instances of a tag contain a number, and all instances are -128 to 127, then it will use an int8 in the Go struct.

接頭辞を変更する

上記の結果をみるとわかるように型の接頭辞にChiがつきます。これを変更するには-eオプションを用います。 ただし、xmlデコーダなど外部からも参照できるように大文字から始める必要があるので注意してください。

# chidley -G -e "Prefix" test.xml

type PrefixChidleyRoot314159 struct {
    PrefixPeople *PrefixPeople `xml:" people,omitempty" json:"people,omitempty"`
}

type PrefixAge struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type PrefixMarried struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type PrefixName struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type PrefixPeople struct {
    PrefixPerson []*PrefixPerson `xml:" person,omitempty" json:"person,omitempty"`
}

type PrefixPerson struct {
    PrefixAge *PrefixAge `xml:" age,omitempty" json:"age,omitempty"`
    PrefixMarried *PrefixMarried `xml:" married,omitempty" json:"married,omitempty"`
    PrefixName *PrefixName `xml:" name,omitempty" json:"name,omitempty"`
}

ちなみに""を指定してあげることで接頭辞をなしにすることもできます。

chidley -G -e "" test.xml
type ChidleyRoot314159 struct {
    People *People `xml:" people,omitempty" json:"people,omitempty"`
}

type Age struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type Married struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type Name struct {
    Text string `xml:",chardata" json:",omitempty"`
}

type People struct {
    Person []*Person `xml:" person,omitempty" json:"person,omitempty"`
}

type Person struct {
    Age *Age `xml:" age,omitempty" json:"age,omitempty"`
    Married *Married `xml:" married,omitempty" json:"married,omitempty"`
    Name *Name `xml:" name,omitempty" json:"name,omitempty"`
}

他にも色々なオプションがありますが、自分が使いそうなところを中心にまとめました。

Reference