いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-232 (xmlのMarshal/Unmarshalで入れ子の要素を指定)

概要

よく忘れるので、ここにメモメモ。。。

xml の Marshal/Unmarshal で入れ子の要素の値を取得する場合、ちゃんと要素毎に type 作って指定していくのが正道だと思いますが、面倒なので一気に取得したいときがあります。

んで、 xml パッケージのドキュメントを見ると以下のように記載されています。

https://pkg.go.dev/encoding/xml@go1.18.4

の Unmarshal の部分に

If the XML element contains a sub-element whose name matches the prefix of a tag formatted as "a" or "a>b>c", unmarshal will descend into the XML structure looking for elements with the given names, and will map the innermost elements to that struct field.

XML要素が "a "または "a>b>c "のようなタグの接頭辞と名前が一致するサブ要素を含む場合、 unmarshalはXML構造体に降りていき、与えられた名前を持つ要素を探し、 最も内側の要素をその構造体フィールドにマップします。(By DeepL先生)

xpathみたいな感じですね。Marshalの場合も同様です。

サンプル

package xmlop

import (
    "encoding/xml"

    "github.com/devlights/gomy/output"
)

// NestedElements -- 入れ子になっている要素を取得するサンプルです。
//
// REFERENCES:
//   - https://pkg.go.dev/encoding/xml@latest#Unmarshal
func NestedElements() error {
    const (
        xmlStr = `
<data>
  <items>
      <item>
          <value>hello</value>
      </item>
      <item>
          <value>world</value>
      </item>
  </items>
</data>`
    )

    type xmldata struct {
        XMLName xml.Name `xml:"data"`             // ルート要素
        Values  []string `xml:"items>item>value"` // 入れ子の要素
    }

    var (
        data xmldata
        err  error
    )

    err = xml.Unmarshal([]byte(xmlStr), &data)
    if err != nil {
        return err
    }

    for _, v := range data.Values {
        output.Stdoutf("[result]", "%v\n", v)
    }

    return nil
}

実行すると以下のようになります。

gitpod /workspace/try-golang (master) $ task run
task: [run] go run . -onetime

ENTER EXAMPLE NAME: xml_nested_elements

[Name] "xml_nested_elements"
[result]             hello
[result]             world


[Elapsed] 87.31µs

参考情報

https://pkg.go.dev/encoding/xml@go1.18.4#Marshal

https://pkg.go.dev/encoding/xml@go1.18.4#Unmarshal

devlights.hatenablog.com

devlights.hatenablog.com

Go言語による並行処理

Go言語による並行処理

Amazon


過去の記事については、以下のページからご参照下さい。

サンプルコードは、以下の場所で公開しています。