Golang模板转义第一个字符。

huangapple go评论78阅读模式
英文:

golang template escape first char

问题

我正在尝试使用标准模板包构建 sitemap XML 文件。
但是第一个字符 "<" 变成了 "<",导致 XML 对客户端不可读。

这是正常的吗?
我该如何使其正常工作?

提前感谢。

英文:

I'm trying to build sitemap XML file with the standard template package.
But the first charset "<" become "&lt ;", and make the XML unreadable for clients.

package main

import (
	&quot;bytes&quot;
	&quot;fmt&quot;
	&quot;html/template&quot;
)

const (
	tmplStr = `{{define &quot;indexSitemap&quot;}}&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;sitemapindex xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&gt;
&lt;sitemap&gt;
    &lt;loc&gt;https://www.test.com/sitemap.xml&lt;/loc&gt;
&lt;/sitemap&gt;
&lt;sitemap&gt;
    &lt;loc&gt;https://www.test.com/events-sitemap.xml&lt;/loc&gt;
&lt;/sitemap&gt;
&lt;sitemap&gt;
    &lt;loc&gt;https://www.test.com/gamesAndTeams-sitemap.xml&lt;/loc&gt;
&lt;/sitemap&gt;
&lt;/sitemapindex&gt;{{end}}`
)

func main() {
	// Parse the template and check for error
	tmpl, parseErr := template.New(&quot;test&quot;).Parse(tmplStr)
	if parseErr != nil {
		fmt.Println(parseErr)
		return
	}

	// Init the writer
	buf := new(bytes.Buffer)

	// Execute and get the template error if any
	tmplExErr := tmpl.ExecuteTemplate(buf, &quot;indexSitemap&quot;, nil)
	if tmplExErr != nil {
		fmt.Println(tmplExErr)
		return
	}

	// Print the content malformed
	fmt.Println(buf)
}

playground golang

Is that normal?
How can I make it works normaly.

Thanks in advance

答案1

得分: 2

你的示例显示你正在使用html/template包,该包会自动对文本进行HTML转义。

如果你想要一个原始的模板引擎,可以使用text/template包,它只是在上下文感知转义的基础上对其进行了封装。

然而,你需要自己确保使用原始模板引擎输出的文本是符合XML规范的。你可以通过在模板中暴露一个escape函数,并通过该函数传递所有的文本,而不是直接写入文本来实现这一点。

[编辑] 看起来这是html/template中的一个bug,如果你省略XML声明中的?,它就可以正常工作。但是,我的建议仍然是,如果不是HTML,最好使用text/template包。实际上,更好的做法是将站点地图描述为一个结构体,而不使用模板,直接进行XML序列化。

英文:

Your example shows you're using the html/template package, which auto-escapes text for html usage.

If you want a raw template engine, use the text/template package instead - the html one just wraps it with context-aware escaping.

However, you'll need to make sure by yourself that the texts you output with the raw template engine are XML-safe. You can do this by exposing some escape function to your template, and passing all texts via this function instead of writing them directly.

[EDIT] It looks like a bug in html/template, if you omit the ? from the xml declaration it works okay. But still my advice stands - if it's not html you're better off using the text/template package. Actually, even better, describe the site map as a struct and don't use a template at all, just XML serialization.

答案2

得分: 1

另请参阅在GitHub上的问题#12496,该问题确认他们不打算修复此问题。

https://github.com/golang/go/issues/12496

可能是因为这是HTML模板包,而您正在尝试生成XML。我怀疑它不知道如何解析带有问号的<?foo>指令。

如果您不打算利用任何HTML自动转义功能,您可能希望改用text/template包。

英文:

Also see issue #12496 on github which confirms they are not planning to fix this.

https://github.com/golang/go/issues/12496

> Probably because this is the HTML templating package and you're trying
> to produce XML. I suspect that it doesn't know how to parse the <?foo>
> directives with the question mark there.
>
> You probably want to use the text/template package instead, if you're
> not going to be taking advantage of any of the HTML auto-escaping
> features.

huangapple
  • 本文由 发表于 2015年9月1日 21:44:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/32333279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定