🤖

GoでSVGファイルを読む方法

2024/06/14に公開

結論

SVGファイルの内容、例えば<polygon>要素のpoints属性値を文字列として読み取るだけでしたら、golang.org/x/net/htmlが使えます。

$ go get golang.org/x/net/html

標準パッケージのencoding/xmlを使う方法もありますが、net/htmlを使う方法であれば型を定義せず使えるので楽です。

実装例

例として日本地図のSVGファイルを開き、すべての<polygon>要素を抽出し、<polygon>要素に含まれるpoints属性値を表示してみます。

package main

import (
	"fmt"
	"os"

	"golang.org/x/net/html"
)

func main() {
	file, err := os.Open("map-full.svg")

	if err != nil {
		panic(err)
	}

	document, err := html.Parse(file)

	if err != nil {
		panic(err)
	}

	result := findAll(document, func(n *html.Node) bool {
		return n.Data == "polygon"
	})

	for i := range result {
		for j := range result[i].Attr {
			if result[i].Attr[j].Key == "points" {
				fmt.Printf("points=%q\n", result[i].Attr[j].Val)
			}
		}
	}
}

func findAll(n *html.Node, cond func(*html.Node) bool) []*html.Node {
	if cond(n) {
		return []*html.Node{n}
	}

	result := []*html.Node{}

	for c := n.FirstChild; c != nil; c = c.NextSibling {
		if found := findAll(c, cond); len(found) > 0 {
			result = append(result, found...)
		}
	}

	return result
}

実行結果

$ go run main.go
points="4 109 6 110 4 111 0 110"
points="48 121 55 123 51 129 39 124 42 122 44 125 46 118"
points="132 113 130 110 132 110 130 108 133 105 132 100 135 108 142 114"
...省略...

ここではpoints属性の値を文字列として表示しただけです。あとは各自で煮るなり焼くなり好きにしてください!

補足

net/htmlでSVGファイルを読み取ると、以下のようなHTMLとして解釈されます。

<html>
  <body>
    ここにSVGファイルの<svg>要素が展開される
  </body>
</html>

特に問題ないかと思いますが、参考まで。

Discussion