python - 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\'"}')
)没有问题
解决方案
{'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)
如您所见,我替换j
为json.dumps(j)
这样 Jinja 将输出正确的 JSON - 您可以看到r
现在包含两个双引号字符串。
在此示例中,您甚至不需要将原始字符串加载到其中j
,因为您可以直接将其传递给 Jinja,但我假设您想在将数据传递到模板之前对其进行修改。
推荐阅读
- r - 在 R 中选择未正确更新的输入
- react-native - 无法从我的 MAP 中删除用户位置图标?
- python - 应用分位数损失函数优化指数平滑模型
- celery - 我是否需要启用 celery beat 才能激活 result_expires?
- keycloak - Mayan-EDMS 与用户 sso 的集成
- php - Laravel Blade 显示数据
- flutter - Flutter 从 api 获取 VideoPlayerController url
- javascript - 从对象数组中的列表中删除索引处的一个元素
- json - 改造 2 流式传输大型 JSON 响应
- openedge - 如何定位包含在多个父小部件中的子小部件以更改属性?