標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

Go で "encoding/xml" で HTML を読む時の注意

単純に xml.Unmarshal を使って

bin, err := io.ReadAll(os.Stdin)
if err != nil {
    return err
}
var htm Html
err = xml.Unmarshal(bin, &htm)
if err != nil {
    return err
}

と HTML を読み込むと、閉じていないタグがあるので:

XML syntax error on line 18: element <meta> closed by </head>

となりがち

間違った対応

xml.HTMLAutoClose というグローバル変数があるので、一見すると

xml.HTMLAutoClose = append(xml.HTMLAutoClose,"meta")

とかすればよさそうだが、間違いだった。"meta" は既に最初からセットされている上に、Unmarshal はこのグローバル変数を呼んでいる気配がない。

正解

NewDecoder でインスタンスを作って、そのフィールドにタグなどをセットすべし。 xml.HTMLAutoClosexml.HTMLEntity は、HTML向けの推奨値だった。

decoder := xml.NewDecoder(os.Stdin)
decoder.Strict = false
decoder.AutoClose = xml.HTMLAutoClose
decoder.Entity = xml.HTMLEntity
decoder.Entity["nbsp"] = " "

var htm Html
err := decoder.Decode(&htm)
if err != nil {
    return err
}