如何打印包含点的键的值

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

How to print the value of a key containing dots

问题

我正在尝试打印一个具有点(.)的键的映射的值。

示例映射:

type TemplateData struct {
    Data map[string]int
}
tpldata := TemplateData{map[string]int{"core.value": 1}}

我尝试了以下方法:

{{ $key := "core.value" }}
{{ .Data.key }}

但是得到了以下错误:

2014/06/17 16:46:17 http: panic serving [::1]:41395: template: template.html:13: bad character U+0024 '$'

以及

{{ .Data."core.value" }}

但是得到了以下错误:

2014/06/17 16:45:07 http: panic serving [::1]:41393: template: template.html:12: bad character U+0022 '"'

请注意,我能够成功打印没有点的键的值。

英文:

I'm trying to print the values of a map, whose keys have a dot (.) on it.

Example map:

type TemplateData struct {
    Data map[string] int
}
tpldata := TemplateData{map[string]int {"core.value": 1}}

I've tried:

{{ $key := "core.value" }}
{{ .Data.key }}

but got:

2014/06/17 16:46:17 http: panic serving [::1]:41395: template: template.html:13: bad character U+0024 '$'

and

{{ .Data."core.value" }}

but got:

2014/06/17 16:45:07 http: panic serving [::1]:41393: template: template.html:12: bad character U+0022 '"'

Note that I'm able to successfully print the value of keys without dots.

答案1

得分: 50

如@martin-ghallager所说,需要使用外部函数来访问这些元素。

幸运的是,标准库已经提供了index函数(它与Martin的dotNotation函数完全相同)。

只需使用以下方式来使用它:

{{ index .Data "core.value" }}

如果键不存在,index函数将返回一个默认值。这对于字典中具有同质数据的情况有效,但在存在异质数据时,它将返回错误的值。在这种情况下,您可以使用以下方式显式设置默认值:

{{ 0 | or (index .Data "core.value") }}
英文:

As @martin-ghallager said, one needs to use an external function to access those elements.

Helpfully, the standard library already provides the index function (which does exactly what Martin's dotNotation function does).

To use it just write:

{{ index .Data "core.value" }}

The index function will return a default value in case the key is not present. This works if your dictionary has homogeneous data, however it will return the wrong value when it is heterogeneous. In such a case you can explicitly set the default with:

{{ 0 | or (index .Data "core.value") }}

答案2

得分: 5

如fabrizioM所述,这违反了包的规范,但是没有什么阻止你创建自己的访问器来使用点符号表示法,可以使用函数映射:

package main

import (
	"fmt"
	"html/template"
	"os"
)

type TemplateData struct {
	Data map[string]int
}

var funcMap = template.FuncMap{
	"dotNotation": dotNotation,
}

func main() {
	data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

	t, err := template.New("foo").Funcs(funcMap).Parse(`{{dotNotation .Data "core.value"}}`)

	if err != nil {
		fmt.Println(err)
	}

	err = t.Execute(os.Stdout, data)

	if err != nil {
		fmt.Println(err)
	}
}

func dotNotation(m map[string]int, key string) int {
	// 显然,你需要验证存在性/nil map
	return m[key]
}

你可以在这里查看代码的运行结果:http://play.golang.org/p/-rlKFx3Ayt

英文:

As fabrizioM has stated, it's against the specs of the package, however there's nothing stopping you creating your own accessor to use dot notation using a function map:

package main

import (
	"fmt"
	"html/template"
	"os"
)

type TemplateData struct {
	Data map[string]int
}

var funcMap = template.FuncMap{
	"dotNotation": dotNotation,
}

func main() {
	data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

	t, err := template.New("foo").Funcs(funcMap).Parse(`{{dotNotation .Data "core.value"}}`)

	if err != nil {
		fmt.Println(err)
	}

	err = t.Execute(os.Stdout, data)

	if err != nil {
		fmt.Println(err)
	}
}

func dotNotation(m map[string]int, key string) int {
	// Obviously you'll need to validate existence / nil map
	return m[key]
}

http://play.golang.org/p/-rlKFx3Ayt

答案3

得分: 2

不可以。根据http://golang.org/pkg/text/template/#Arguments中的规范,键必须是字母数字组合。

  • 数据的键名必须是一个映射(map)中的键,以句点开头,例如
    .Key
    结果将是由键索引的映射元素的值。
    键调用可以与字段组合到任意深度:
    .Field1.Key1.Field2.Key2
    尽管键必须是字母数字标识符,但与字段名不同,它们不需要以大写字母开头。
    键也可以在变量上进行求值,包括链式调用:
    $x.key1.key2

您仍然可以通过遍历映射来打印它。

package main

import (
	"fmt"
	"html/template"
	"os"
)

type TemplateData struct {
	Data map[string]int
}

func main() {
	data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

	t, err := template.New("foo").Parse(`{{range $key, $value := .Data}}
   {{$key}}: {{$value}}
{{end}}`)
	if err != nil {
		fmt.Println(err)
	}
	err = t.Execute(os.Stdout, data)
	if err != nil {
		fmt.Println(err)
	}
}

http://play.golang.org/p/6xB_7WQ-59

英文:

No you can't.
According to the specs in http://golang.org/pkg/text/template/#Arguments, the key must be alphanumeric

- The name of a key of the data, which must be a map, preceded
  by a period, such as
	.Key
  The result is the map element value indexed by the key.
  Key invocations may be chained and combined with fields to any
  depth:
    .Field1.Key1.Field2.Key2
  Although the key must be an alphanumeric identifier, unlike with
  field names they do not need to start with an upper case letter.
  Keys can also be evaluated on variables, including chaining:
    $x.key1.key2

You can still print it by iterating over the Map
package main

import (
	"fmt"
	"html/template"
	"os"
)

type TemplateData struct {
	Data map[string]int
}

func main() {
	data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

	t, err := template.New("foo").Parse(`{{range $key, $value := .Data}}
   {{$key}}: {{$value}}
{{end}}`)
	if err != nil {
		fmt.Println(err)
	}
	err = t.Execute(os.Stdout, data)
	if err != nil {
		fmt.Println(err)
	}
}

http://play.golang.org/p/6xB_7WQ-59

答案4

得分: 0

我遇到了一个类似的问题,我的密钥名称中包含 -.,例如 test-keytest.key

我是这样解决的:

    {{ with secret "secret/path/test"}}
       {{ range $k, $v := .Data }}
          {{ $k }}:{{ $v }}
          {{ end }}
    {{ end }}

希望这对某人有帮助...

英文:

I had a similar issue where my key names in secret vault had - and . in it for example

test-key or test.key

If solved it like this

    {{ with secret "secret/path/test"}}
       {{ range $k, $v := .Data }}
          {{ $k }}:{{ $v }}
          {{ end }}
    {{ end }}

Hope this will help someone...

答案5

得分: -1

同样适用于 Vault 模板,当将密钥导出为环境变量时,以下代码对我有效:

{{- with secret "secret/path/mysecret" -}}

export MYVAR="{{ index .Data.data "mykey"}}"

{{- end }}
英文:

Similarly for vault templates when exporting secrets as envvars this worked for me:

{{- with secret "secret/path/mysecret" -}}

export MYVAR="{{ index .Data.data "mykey"}}"

{{- end }}

huangapple
  • 本文由 发表于 2014年6月17日 23:20:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/24267608.html
匿名

发表评论

匿名网友

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

确定