You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang中XML转义字符问题:如何保留单引号而非转义码?

问题:Golang XML序列化时单引号被转义为'如何解决?

我编写了如下Golang程序:

package main

import (
    "encoding/xml"
    "fmt"
)

type XMLData struct {
    XMLName xml.Name `xml:"tags"`
    Tags    []Tag    `xml:"tag"`
}

type Tag struct {
    Text string `xml:"text,attr"`
}

func main() {
    var XMLFile XMLData // 注:原代码中XMLDate为笔误,正确应为XMLData
    XMLFile.Tags = append(XMLFile.Tags, Tag{"Yes, I'm."})

    out, err := xml.MarshalIndent(&XMLFile, "", "  ")
    if err != nil {
        panic(err)
    }

    fmt.Println(string(out))
}

运行该程序时,我期望得到如下输出:

<tags>
  <tag text="Yes, I'm."></tag>
</tags>

但实际得到的输出却是:

<tags>
  <tag text="Yes, I&#39;m."></tag>
</tags>

原本的单引号被替换成了转义码&#39;,请问该如何解决这个问题?


解决方案

Go标准库encoding/xml在序列化XML属性时,会自动转义特殊字符,这是符合XML规范的行为。若要避免单引号被转义,可通过以下两种方式处理:

1. 自定义XML Marshaler接口

实现xml.Marshaler接口,手动控制属性输出逻辑,跳过单引号转义:

package main

import (
    "encoding/xml"
    "fmt"
)

type XMLData struct {
    XMLName xml.Name `xml:"tags"`
    Tags    []Tag    `xml:"tag"`
}

type Tag struct {
    Text string `xml:"text,attr"`
}

// 为Tag实现xml.Marshaler接口
func (t Tag) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
    // 手动添加属性,直接使用原始文本
    start.Attr = append(start.Attr, xml.Attr{
        Name:  xml.Name{Local: "text"},
        Value: t.Text,
    })
    // 写入开始标签并结束(Tag无嵌套元素)
    if err := e.EncodeToken(start); err != nil {
        return err
    }
    return e.EncodeToken(xml.EndElement{Name: start.Name})
}

func main() {
    var XMLFile XMLData
    XMLFile.Tags = append(XMLFile.Tags, Tag{"Yes, I'm."})

    out, err := xml.MarshalIndent(&XMLFile, "", "  ")
    if err != nil {
        panic(err)
    }

    fmt.Println(string(out))
}

这段代码通过自定义序列化逻辑,绕过标准库的转义规则,运行后可得到期望输出。

2. 序列化后替换转义字符

若不想自定义Marshaler,可在序列化完成后,将&#39;替换回单引号:

package main

import (
    "encoding/xml"
    "fmt"
    "strings"
)

type XMLData struct {
    XMLName xml.Name `xml:"tags"`
    Tags    []Tag    `xml:"tag"`
}

type Tag struct {
    Text string `xml:"text,attr"`
}

func main() {
    var XMLFile XMLData
    XMLFile.Tags = append(XMLFile.Tags, Tag{"Yes, I'm."})

    out, err := xml.MarshalIndent(&XMLFile, "", "  ")
    if err != nil {
        panic(err)
    }

    // 替换转义的单引号
    result := strings.ReplaceAll(string(out), "&#39;", "'")
    fmt.Println(result)
}

这种方法更简洁,但需注意:若属性值本身包含&#39;字符串,替换会导致错误,仅适用于确定无此类场景的情况。


内容的提问来源于stack exchange,提问作者12iq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 21:55:11