【Go】xmlのstruct定義ベストプラクティス

Goのxmlパーサである、encoding/xmlのパースベストプラクティス(自分調べ)です。

通常のパース

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <item>
    <title>hogehoge</title>
    <link>https://cateiru.com</link>
  </item>
</data>
type Data struct {
  Item struct {
    Title string `xml:"title"`
    Link  string `xml:"link"`
  } `xml:"item"`
}

go.dev

複数要素がある場合

複数の要素がある場合は、型を配列にすることでそこに配列として格納されるようになる。配列はstring以外でもstructなどでも定義することができる。

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <item>hoge</item>
  <item>huga</item>
  <item>foo</item>
</data>
type Data struct {
  Items []string `xml:"item"`
}

go.dev

omitempty

フィールドタグに,omitemptyを追加するとその属性はオプショナルになる。
空の場合の値は型によって様々で、stringであれば空文字列になるしポインタならnilになる。基本は、omitemptyをつけたのであればポインタで指定して存在しない場合はnilにしてしまうと良さそう。

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <item>
    <title>hogehoge</title>
  </item>
</data>
type Data struct {
  Item struct {
    Title string `xml:"title"`
    Link  string `xml:"link,omitempty"`
  } `xml:"item"`
}

go.dev

タグの属性を取得する

フィールドタグをname,attrのようにすることで属性値を取得することができる。

<?xml version="1.0" encoding="UTF-8"?>
<data>
  <item name="item-name">
    <title>hogehoge</title>
    <link>https://cateiru.com</link>
  </item>
</data>
type Data struct {
  Item struct {
    Name  string `xml:"name,attr"`
    Title string `xml:"title"`
    Link  string `xml:"link"`
  } `xml:"item"`
}

go.dev

タグの属性とtextContentを取得する

<Code type="震央地名">950</Code>のようなtextContentがstringとなるような要素で、属性付きのものを取得する場合はフィールドタグに,chardataを追加すると良い。

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <Code type="震央地名">950</Code>
</data>
type Data struct {
    Code struct {
        Type  string `xml:"type,attr"`
        Value string `xml:",chardata"`
    } `xml:"Code"`
}

go.dev

名前空間が存在する

<jmx_eb:Magnitude type="M" description="M7.1">7.1</jmx_eb:Magnitude>のように要素名に:がついている場合、その左側は名前空間となる。

取得する際は、名前空間は無視されるようなので特に意識しなくて良い。

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <jmx_eb:Magnitude type="M" description="M7.1">7.1</jmx_eb:Magnitude>
</data>
type Data struct {
    Magunitude struct {
        Type  string `xml:"type,attr"`
        Desc  string `xml:"description,attr"`
        Value string `xml:",chardata"`
    } `xml:"Magnitude"`
}

go.dev