go 标准库 `encoding/xml` 默认不解析 dtd 中声明的实体(如 ``)遇到 `&n;` 会报“invalid character entity”错误;需手动初始化 `xml.decoder` 并设置 `entity` 映射表,才能正确解析自定义实体。
在 Go 中解析含自定义 XML 实体(例如 )的文档时,直接使用 xml.Unmarshal 或 xml.NewDecoder(reader).Decode() 会失败,并抛出类似 XML syntax error: invalid character entity &n; 的错误。这是因为 Go 的 encoding/xml 包不自动解析 DTD,也不会从文档中提取并注册 声明——它仅提供一个可由调用方预设的 Entity map[string]string 字段,用于静态映射实体名到其替换文本。
要正确解析,必须显式创建 *xml.Decoder,并在调用 Decode() 前为其 Entity 字段赋值。例如:
func parseWithEntities(xmlData string) error {
type JMdict struct {
Pos string `xml:"pos"`
}
var jmd JMdict
decoder := xml.NewDecoder(strings.NewReader(xmlData))
// 手动注册实体:key 是实体名(不含 & 和 ;),value 是实际替换内容
decoder.Entity = map[string]string{
"n": "noun (common) (futsuumeishi)",
"v": "verb (godan)",
"adj": "adjective (keiyoushi)",
}
if err := decoder.Decode(&jmd); err != nil {
return fmt.Errorf("XML decode failed: %w", err)
}
fmt.Printf("Parsed pos: %q\n", jmd.Pos) // 输出: "noun (common) (futsuumeishi)"
return nil
}⚠️ 注意事项:

总结:Go 的 XML 解析器设计强调安全与确定性,主动放弃自动 DTD 处理以避免外部实体攻击和全局状态污染。因此,处理自定义实体是明确的、显式的职责——开发者需承担解析前的实体映射工作,这也使行为更可控、更易测试。