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

Go 1.20:xml.Marshal生成XML时如何保留未编码URL?站点地图开发

问题:XML序列化时避免URL编码(Go 1.20)

我正在为网站开发站点地图,不希望URL被编码。使用Go 1.20版本,当前代码如下:

package main

import (
    "encoding/xml"
    "fmt"
)

func main() {
    testXML()
}

type ElementTree struct {
    Href string `xml:"href,attr"`
}

func testXML() {
    e := ElementTree{
        Href: "https://www.test.com?a=1&b=2",
    }
    indent, err := xml.MarshalIndent(e, "", "\t")
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    //<ElementTree href="https://www.test.com?a=1&amp;b=2"></ElementTree>
    fmt.Println(string(indent))
}

当前代码输出为:

<ElementTree href="https://www.test.com?a=1&amp;b=2"></ElementTree>

我期望得到的结果是:

<ElementTree href="https://www.test.com?a=1&b=2"></ElementTree>

请问如何实现该需求?XML属性中的URL是否必须进行编码?


实现方法

Go标准库的encoding/xml默认会转义XML属性里的特殊字符(比如&),这是符合XML规范的行为。要跳过转义,得自定义xml.Marshaler接口来手动处理序列化逻辑:

package main

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

type ElementTree struct {
    Href string `xml:"href,attr"`
}

// 自定义MarshalXML方法,绕过默认转义
func (e ElementTree) MarshalXML(w io.Writer, start xml.StartElement) error {
    // 直接将原始URL作为属性值添加
    start.Attr = append(start.Attr, xml.Attr{
        Name:  xml.Name{Local: "href"},
        Value: e.Href,
    })
    // 写入开始标签
    if err := start.WriteTo(w); err != nil {
        return err
    }
    // 写入结束标签(当前结构体没有子元素)
    end := xml.EndElement{Name: start.Name}
    return end.WriteTo(w)
}

func main() {
    testXML()
}

func testXML() {
    e := ElementTree{
        Href: "https://www.test.com?a=1&b=2",
    }
    indent, err := xml.MarshalIndent(e, "", "\t")
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Println(string(indent))
}

运行这段代码就能得到你想要的未编码URL输出。

XML属性中的URL是否必须编码?

严格按照XML规范,属性值里的&必须转义成&amp;——因为&在XML里是特殊字符,用来标识实体引用的起始,不转义会导致XML解析器报错。

不过站点地图的场景比较特殊,大多数搜索引擎能兼容未转义的&,但这不代表格式合法。如果硬要输出未转义的URL,得承担风险:部分严格的XML解析工具可能无法正确读取你的站点地图。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:23:12