Golang模板变量中转义点的处理方法

Golang模板变量中转义点的处理方法 我正在将来自外部JSON源(我无法控制其格式)的数据输入到一个模板中。但有些名称中包含点号。因此,我最终得到了一个模板变量 {{.Map.first.name}},其中 "first.name" 是 Map 中的一个键。我该如何转义这个点号?或者有没有其他技巧?我尝试过 {{.Map."first.name"}},但这会导致 panic(错误的字符 ‘"’)。

以下是一个演示该问题的示例程序。

非常感谢

package main

import (
        "os"
        "text/template"
        "time"
)

const atemplate = `Look at this:
{{range .}} {{.Name}} {{.Count }} 
{{.JoinDate}} {{.JoinString}} {{.Map.post.code}}
{{end}}`

type Record struct {
        Name       string
        Count      int
        JoinDate   time.Time
        JoinString string
        Map        map[string]string
}

func main() {
        tmpl, err := template.New("test").Parse(atemplate)
        if err != nil {
                panic(err)
        }
        var r []Record
        r = append(r, Record{
                Name:       "Suzanne",
                Count:      236,
                JoinDate:   time.Date(2009, time.November, 10, 23, 0, 0, 0, time.Local),
                JoinString: "rs",
                Map:        map[string]string{"key": "value", "post.code": "5068"},
        })
        err = tmpl.Execute(os.Stdout, r)
        if err != nil {
                panic(err)
        }
}

更多关于Golang模板变量中转义点的处理方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

API文档页面中唯一一个以 post 开头的键是 postal_code

更多关于Golang模板变量中转义点的处理方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


非常感谢。您的解决方案 {{index … }} 在我的测试代码中有效,但在实际代码中无效……所以我正在处理的结构显然与我想象的不同!数据来自 github.com/stripe/stripe-go 模块。我必须深入研究一下。

是的……问题不在于Stripe变量……而在于其他应用程序添加的一堆元数据变量。Stripe允许客户端添加元数据映射,而我正试图汇总由3个不同应用程序生成的收费数据,这些应用程序在元数据中使用了不同的名称😦……并且有些名称包含点号,有些包含空格。

但我已经发现了我对结构的错误假设,并且“index”函数运行良好。非常感谢。

您可以在模板中使用 index 函数。

{{index .Map "post.code"}}

或者,如果您事先知道键,不要将其转储到 map[string]string 中,而是将其解组到正确定义的结构体中。

type TheForeignJson struct {
  PostCode string `json:"post.code"`
}

type Record struct {
        Name       string
        Count      int
        JoinDate   time.Time
        JoinString string
        Map        TheForeignJson
}

在Go模板中处理包含点号的键名,可以使用index函数来访问map中的值。index函数可以处理包含特殊字符的键名。

以下是修改后的示例代码:

package main

import (
    "os"
    "text/template"
    "time"
)

const atemplate = `Look at this:
{{range .}} {{.Name}} {{.Count}} 
{{.JoinDate}} {{.JoinString}} {{index .Map "post.code"}}
{{end}}`

type Record struct {
    Name       string
    Count      int
    JoinDate   time.Time
    JoinString string
    Map        map[string]string
}

func main() {
    tmpl, err := template.New("test").Parse(atemplate)
    if err != nil {
        panic(err)
    }
    
    var r []Record
    r = append(r, Record{
        Name:       "Suzanne",
        Count:      236,
        JoinDate:   time.Date(2009, time.November, 10, 23, 0, 0, 0, time.Local),
        JoinString: "rs",
        Map: map[string]string{
            "key":       "value",
            "post.code": "5068",
            "first.name": "John",
        },
    })
    
    err = tmpl.Execute(os.Stdout, r)
    if err != nil {
        panic(err)
    }
}

对于嵌套的map结构,比如{{.Map.first.name}}这种情况,可以这样处理:

const nestedTemplate = `{{index .Map "first.name"}}`

// 或者对于多层嵌套
const complexTemplate = `{{$data := .}}
{{range $key, $value := .Map}}
    Key: {{$key}}, Value: {{$value}}
{{end}}
{{index .Map "first.name"}}`

index函数的工作方式:

  • index map key - 返回map中对应key的值
  • index slice index - 返回slice中对应索引的值
  • index array index - 返回array中对应索引的值

对于你的具体问题{{.Map.first.name}},正确的写法是:

{{index .Map "first.name"}}

这样就能正确处理包含点号的键名,而不会引发解析错误。

回到顶部