Golang文本模板常见问题解析

Golang文本模板常见问题解析 我正在基于Go模板构建一种代码生成器,但在处理某些字符时遇到了问题。

例如,如果我的模板中有这行代码:

public class {{.Name}}Validator : AbstractValidator<{{.Name}}Input>

在我的输出文件中会被转换为:

public class GetLoginMarketColorSettingByLoginIDValidator : AbstractValidator&lt; GetLoginMarketColorSettingByLoginIDInput &gt;

另一个出现问题的代码行:

RuleFor(x => x.{{.Name}}).Cascade(CascadeMode.StopOnFirstFailure){{.ValidationString}};

而ValidationString是在我的代码中构建的,应该是:

(.NotEmpty().Length(1,15).WithMessage("Not a Valid LoginID");

但这行代码生成的结果是:

RuleFor(x => x.LoginID).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty().Length(1,15).WithMessage(&#34;Not a Valid LoginID&#34;);

看起来模板系统应用了URL编码,或者当特殊字符靠近替换标签({{}})时会变得混乱。

有什么解决这个问题的提示吗?

提前感谢。


更多关于Golang文本模板常见问题解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

你好,Yamil,你使用的是 text/template 包还是 html/template?我像你一样使用 text/template 来生成代码,并且没有遇到任何 HTML 实体编码的问题。

更多关于Golang文本模板常见问题解析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,你说得对!! 当我添加了 template.ParseFiles(…) 到我的代码中时,我的编辑器自动在我的导入中加载了 html/template,而我没有检查这一点!!!

谢谢!!!

template.ParseFiles(…)

在Go模板中,默认情况下会对内容进行HTML转义,这是为了防止XSS攻击。你遇到的问题正是由于模板引擎自动将特殊字符(如 <>")转换为对应的HTML实体(如 &lt;&gt;&#34;)。要解决这个问题,可以使用 template.HTML 类型来标记内容为安全的HTML,从而避免转义。

解决方案:

  1. 对于模板中的静态内容:使用 template.HTML 类型包装你的字符串,告诉模板引擎不要转义。
  2. 对于动态生成的内容:确保在传递到模板之前,将字符串转换为 template.HTML 类型。

示例代码:

假设你的模板数据是一个结构体,其中 NameValidationString 字段需要避免转义。你可以这样处理:

package main

import (
	"html/template"
	"os"
)

type TemplateData struct {
	Name             string
	ValidationString template.HTML
}

func main() {
	tmpl := `public class {{.Name}}Validator : AbstractValidator<{{.Name}}Input>

RuleFor(x => x.{{.Name}}).Cascade(CascadeMode.StopOnFirstFailure){{.ValidationString}};`

	data := TemplateData{
		Name:             "GetLoginMarketColorSettingByLoginID",
		ValidationString: template.HTML(`.NotEmpty().Length(1,15).WithMessage("Not a Valid LoginID");`),
	}

	t := template.Must(template.New("codegen").Parse(tmpl))
	t.Execute(os.Stdout, data)
}

输出将会是:

public class GetLoginMarketColorSettingByLoginIDValidator : AbstractValidator<GetLoginMarketColorSettingByLoginIDInput>

RuleFor(x => x.GetLoginMarketColorSettingByLoginID).Cascade(CascadeMode.StopOnFirstFailure).NotEmpty().Length(1,15).WithMessage("Not a Valid LoginID");

关键点:

  • 使用 template.HTML 类型包装任何包含HTML或特殊字符的字符串,以防止转义。
  • 确保在构建 ValidationString 时,将其转换为 template.HTML 类型,例如:template.HTML(yourString)

如果你的 ValidationString 是动态生成的,在代码中这样处理:

validationStr := ".NotEmpty().Length(1,15).WithMessage(\"Not a Valid LoginID\");"
data.ValidationString = template.HTML(validationStr)

这样,模板引擎就不会对内容进行转义,特殊字符会按原样输出。

回到顶部