Golang文本模板常见问题解析
Golang文本模板常见问题解析 我正在基于Go模板构建一种代码生成器,但在处理某些字符时遇到了问题。
例如,如果我的模板中有这行代码:
public class {{.Name}}Validator : AbstractValidator<{{.Name}}Input>
在我的输出文件中会被转换为:
public class GetLoginMarketColorSettingByLoginIDValidator : AbstractValidator< GetLoginMarketColorSettingByLoginIDInput >
另一个出现问题的代码行:
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("Not a Valid LoginID");
看起来模板系统应用了URL编码,或者当特殊字符靠近替换标签({{}})时会变得混乱。
有什么解决这个问题的提示吗?
提前感谢。
更多关于Golang文本模板常见问题解析的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好,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实体(如 <、>、")。要解决这个问题,可以使用 template.HTML 类型来标记内容为安全的HTML,从而避免转义。
解决方案:
- 对于模板中的静态内容:使用
template.HTML类型包装你的字符串,告诉模板引擎不要转义。 - 对于动态生成的内容:确保在传递到模板之前,将字符串转换为
template.HTML类型。
示例代码:
假设你的模板数据是一个结构体,其中 Name 和 ValidationString 字段需要避免转义。你可以这样处理:
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)
这样,模板引擎就不会对内容进行转义,特殊字符会按原样输出。

