如何解决转到模板列表变量以从模板替换
所以我使用的是 go 模板,我希望能够通过从模板中获取变量列表来动态生成配置映射。
准确地说,假设我有一个看起来像这样的文件名 test.yaml.tmpl:
car:
color: {{ .color }}
model: {{ .model }}
我希望能够在我的 go 代码中生成一个包含 [color model]
或 [.color .model]
的数组,我可以自己处理这些点。
我查看了不同的选项,但无法得到我想要的结果,我得到的最接近的是使用 template.Root.Nodes
提取变量值,但它并不完美,并且可能在特定条件下产生不必要的错误。>
编辑 1
我尝试使用树,这给了我这种类型的输出:
&{test.yaml.tmpl test.yaml.tmpl ---
car:
color: {{ .color }}
model: {{ .model }}
0 ---
car:
color: {{ .color }}
model: {{ .model }}
[] <nil> [{8 995 45} {11 409 {{ 22} {0 0 0}] 1 [] map[] 0 0}
问题是我无法访问字段节点,访问树时可用的唯一方法是:
仍然无法获取字段列表。
编辑 2
当打印 tree.Root.Nodes 时,我得到了完整的 yaml 输出,其中包含要替换的变量:
(*parse.ActionNode)(0xc00007f1d0)({{ .color }}),(*parse.TextNode)(0xc00007f200)
解决方法
好吧,您可以使用您知道的正则表达式。 ;P
package main
import (
"fmt"
"regexp"
)
var fieldSearch = regexp.MustCompile(`{{ \..* }}`)
func main() {
template := `
car:
color: {{ .color }}
model: {{ .model }}
`
res := fieldSearch.FindAll([]byte(template),-1)
for i := range res {
// this is just for readability you can replace this with
// magic numbers if you want
res[i] = res[i][len("{{ .") : len(res[i])-len(" }}")]
}
for _,v := range res {
fmt.Println(string(v))
}
}
,
好的,所以我使用@icza How to get a map or list of template 'actions' from a parsed template?发布的链接并处理返回的字符串以获得我需要的内容,结果如下:
func main() {
node := listNodeFields(t.Tree.Root)
var tNode []string
for _,n := range node {
r := n[len("{{.* .") : len(n)-len(" .*}}")]
if strings.Contains(n,"or ") {
r = r + " or"
}
tNode = append(tNode,r)
}
config := make(map[string]string)
for _,n := range tNode {
var value string
var present bool
if strings.Contains(n," or") {
n = strings.Replace(n," or","",-1)
value,present = os.LookupEnv(n)
if !present {
fmt.Println("The variable " + value + " is not set but there is a default value in template " + t.Name() + "!")
}
} else {
value,present = os.LookupEnv(n)
if !present {
return nil,errors.New("The variable " + f + " is not set but exists in the template " + t.Name() + "!")
}
}
config[n] = value
}
}
func listNodeFields(node parse.Node) []string {
var res []string
if node.Type() == parse.NodeAction {
res = append(res,node.String())
}
if ln,ok := node.(*parse.ListNode); ok {
for _,n := range ln.Nodes {
res = append(res,listNodeFields(n)...)
}
}
return res
}
因为我不想在使用默认值的情况下产生错误,所以我添加了一个特定的处理,以免从模板的 missingkey=error 选项中获取错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。