dongye9820 2019-01-18 08:58
浏览 282
已采纳

在JSON模板中转义值

Using html/template to create JSON output. Code snippet is as follows (playground):

package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "html/template"
)

const tpl = `
{
    "key": "{{- .Value -}}" // Replace with js .Value to get another error
}
`

func main() {
    t, err := template.New("").Parse(tpl)
    if err != nil {
        panic(err)
    }
    var buf bytes.Buffer
    err = t.Execute(&buf, struct{
        Value string
    }{"Test\\ > \\ Value"})
    if err != nil {
        panic(err)
    }
    data := make(map[string]string)
    err = json.Unmarshal(buf.Bytes(), &data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%v
", data)
}

If I try to insert .Value as is - then I get the following error:

panic: invalid character ' ' in string escape code

This is because \\ becomes \ and \ + space is incorrect escaping in JSON. I can fix this by adding js function to template:

const tpl = `
{
    "key": "{{- js .Value -}}"
}
`

In that case it fails with another error:

panic: invalid character 'x' in string escape code

This is because js function converts > sign to \x3c and \x is incorrect escaping in JSON.

Any ideas how to get a universal function that correctly escapes strings for JSON? Is there an alternative way (e.g. an external library) to create JSON templates considering all these difficulties?

  • 写回答

1条回答 默认 最新

  • dsyua2828 2019-01-18 11:10
    关注

    Option 0

    https://play.golang.org/p/4DMTAfEapbM

    As @Adrian suggested, using text/template, so we do need just one unescape and the end.

    Option 1

    https://play.golang.org/p/oPC1E6s-EwB

    Enscape before excute template, then unenscape twice when you want the string value.

    Option 2

    https://play.golang.org/p/zD-cTO07GZq

    Replace "\\" with "\\\\".

    }{"Test\\ > \\ Value"})
    to
    }{"Test\\\\ > \\\\ Value"})
    

    one more

    "// " comment is not supported in json.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?