用字典格式化 JSON

formatting JSON with a dict

我正在为技术用户编写一些代码,以便在 JSON 中传递变量占位符,并附有一个字典来定义每个变量。我想用值替换这些变量,最终需要将其放入 Python 字典中。想象一下我从这个开始:

>>> json_in = """
{
    "sidebar": {
        "type": "sidebar",
        "title": "<h1>Vulnerability Data</h1>",
        "description": {md_html}
    },
    "widgets": [
        {
            "name": "Map",
            "itemId": {item_id},
            "showNavigation": false
        }
    ]
}"""
>>> args = {'md_html': '<super_long_html_string>', 'item_id': 'abcdef12345'}

如果我尝试使用 json_in.format(**args) 之类的格式,我只会在遇到第一个左花括号(“侧边栏”之前)时遇到 KeyError,该格式会尝试读取。双大括号在 format() 中将它们转义,但是这个 JSON 可能有数千行长,所以我真的不想让人们做大量的重新格式化。我想我可以尝试在 format() 之前用 Python 编辑 JSON。我必须避免破坏格式字符串中的花括号,所以这看起来变得不必要地复杂了。 Python 通常有简单的解决方案,所以我错过了什么?


我走的另一条路就是首先将其创建为 Python 字典。搜索 JSONisms 并替换为 Python 等效项(例如:falseFalsetrueTrue)很容易。我没有格式化字符串 ({item_id}),而是使用变量 (item_id) 来结束这样的事情:

>>> md_html = '<super_long_html_string>'
>>> item_id = 'abcdef12345'
>>> dict_in = {
    "sidebar": {
        "type": "sidebar",
        "title": "<h1>Vulnerability Data</h1>",
        "description": md_html
    },
    "widgets": [
        {
            "name": "Map",
            "itemId": item_id,
            "showNavigation": False
        }
    ]
}

问题是变量 md_htmlitem_id 在这个例子中是硬编码的,我想接受用户传入的任何内容(见上面的 args dict ).如果我可以创建一个带有占位符的字典并用提供的输入替换它们,那将解决我的问题。

我会使用 jq library 来定义这样一个 JSON 模板。

import jq


json_in = """
{
    "sidebar": {
        "type": "sidebar",
        "title": "<h1>Vulnerability Data</h1>",
        "description": $md_html
    },
    "widgets": [
        {
            "name": "Map",
            "itemId": $item_id,
            "showNavigation": false
        }
    ]
}"""


args = {'md_html': '<super_long_html_string>', 'item_id': 'abcdef12345'}

result = jq.compile(json_in, args=args).input("")

如果您可以控制 json_in,请查看 Template Strings

from string import Template
json_in = """
{
    "sidebar": {
        "type": "sidebar",
        "title": "<h1>Vulnerability Data</h1>",
        "description": $md_html
    },
    "widgets": [
        {
            "name": "Map",
            "itemId": $item_id,
            "showNavigation": false
        }
    ]
}"""
args = {'md_html': '<super_long_html_string>', 'item_id': 'abcdef12345'}
Template(json_in).substitute(args)

输出

{
    "sidebar": {
        "type": "sidebar",
        "title": "<h1>Vulnerability Data</h1>",
        "description": <super_long_html_string>
    },
    "widgets": [
        {
            "name": "Map",
            "itemId": abcdef12345,
            "showNavigation": false
        }
    ]
}

我想你会想要在字符串周围加上引号,我只是让 json 尽可能靠近你的问题。