0

json.load を使用してロードしている JSON データを含むファイルがあります。別のデータ フィールドを参照する変数を json データに入れたいとします。この参照をPythonで処理するにはどうすればよいですか?

例えば:

{
  "辞書" : {
    "list_1": [
      「アイテム_1」
    ]、

    "list_2" : [
      "$dictionary.list_1"
    ]
  }
}

$ に出くわしたら、list_2 で Dictionary.list_1 からデータを取得し、Python コードで記述したかのように list_2 を拡張します。

jsonData["辞書"]["list_2"].extend(jsonData["辞書"]["list_1"])
4

1 に答える 1

1

私の知る限り、参照を行うための JSON 標準には何もありません。私の最初の提案は、 Node Anchorsの形式で参照を持つYAMLを使用することです。Python には、それらをサポートする YAML の適切な実装があります。

そうは言っても、JSON を使用することに設定されている場合は、独自の実装を展開する必要があります。

考えられる例の 1 つ (これは、dict の場合はあいまいであるため、参照された配列によって現在の配列を拡張しませんが、参照を参照する値で置き換えます) を以下に示します。エラーチェックを自分で追加するか、不正な参照がないことを保証する必要がある不正な参照を処理しないことに注意してください。置き換えるのではなく拡張するように変更することもできますが、ユースケースを私よりよく知っているので、そのように指定することができます。これは、出発点を提供することを目的としています。

def resolve_references(structure, sub_structure=None):
    if sub_structure is None:
        return resolve_references(structure, structure)
    if isinstance(sub_structure, list):
        tmp = []
        for item in sub_structure:
            tmp.append(resolve_references(structure, item))
        return tmp

    if isinstance(sub_structure, dict):
        tmp = {}
        for key,value in sub_structure.items():
            tmp[key] = resolve_references(structure, value)
        return tmp

    if isinstance(sub_structure, str) or isinstance(sub_structure, unicode):
        if sub_structure[0] != "$":
            return sub_structure

        keys = sub_structure[1:].split(".")
        def get_value(obj, key):
            if isinstance(obj, dict):
                return obj[key]
            if isinstance(obj, list):
                return obj[int(key)]
            return value

        value = get_value(structure, keys[0])
        for key in keys[1:]:
            value = get_value(value, key)
        return value
    return sub_structure

使用例:

>>> import json
>>> json_str = """
... {
...   "dictionary" : {
...     "list_1" : [
...       "item_1"
...     ],
... 
...     "list_2" : "$dictionary.list_1"
...   }
... }
... """
>>> obj = json.loads(json_str)
>>> resolve_references(obj)
{u'dictionary': {u'list_2': [u'item_1'], u'list_1': [u'item_1']}}
于 2013-02-21T23:05:10.333 に答える