首页 > 解决方案 > Jinja2 呈现包含引号和双引号的 json 值的问题

问题描述

我正在尝试使用包含引号和双引号的字符串值加载 json 文件。

如果我加载此文件(json 或 yaml)并在 jinja2 渲染模板中使用它,如果我尝试使用 json 或 yaml 解析器加载结果,则会出现错误。

例如这个 json 文件:

{
  "k": "\"v1\"='v2'"
}

以下代码失败(使用 json 解析器):

import json
from jinja2 import Environment

j = json.loads('{"k": "\\"v1\\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': j})
# print(r)=> {'k': '"v1"=\'v2\''}
y = json.loads(r)

有错误:json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

或者使用 yaml 解析器:

import yaml
from jinja2 import Environment

j = yaml.safe_load('{"k": "\\"v1\\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': j})
# print(r)=> {'k': '"v1"=\'v2\''}
y = yaml.safe_load(r)

返回此错误:yaml.parser.ParserError: while parsing a flow mapping in "<unicode string>", line 1, column 1: {'k': '"v1"=\'v2\''}

我认为错误出在我的 jinja2 渲染参数中,但是如何解决呢?

注意:如果我只使用双引号 ( j = json.loads('{"k": "\\"v1\\""}')) 或只使用单引号 ( j = json.loads('{"k": "\'v2\'"}'))没有问题

标签: pythonjsonyamljinja2

解决方案


{'k': '"v1"=\'v2\''}既不是有效的 JSON 也不是 YAML。这是因为 JSON 专门支持双引号字符串,而 YAML 确实支持单引号字符串,但它们不处理转义序列。

Jinja 以这种方式呈现它,因为它是有效的 Python。Jinja 不知道您想将其解析为 JSON 或 YAML。如果您想稍后再次将其加载为 JSON,则必须将结构序列化为 JSON:

import json
from jinja2 import Environment

j = json.loads('{"k": "\\"v1\\"=\'v2\'"}')
t = Environment().from_string('{{ d }}')
r = t.render({'d': json.dumps(j)})
# print(r)=> {"k": "\"v1\"='v2'"}
y = json.loads(r)
print(y)

如您所见,我替换jjson.dumps(j)这样 Jinja 将输出正确的 JSON - 您可以看到r现在包含两个双引号字符串。

在此示例中,您甚至不需要将原始字符串加载到其中j,因为您可以直接将其传递给 Jinja,但我假设您想在将数据传递到模板之前对其进行修改。


推荐阅读