オブジェクトの固定キーに基づいて、ドキュメント内のオブジェクトに使用されるクラスを設定できるように、JSON ドキュメントの解析をカスタマイズしようとしています。
たとえば、「account」という値を持つ「type」のキーを持つ JSON 内の任意の場所にあるオブジェクトは、 のインスタンスを作成する必要がありますAccount
。
{"type": "account", "account_id": "1234"}
値「user」を持つ「type」のキーを持つオブジェクトは、のインスタンスを作成する必要がありますUser
。
{"type": "user", "username": "jane", "email": "jane@example.com"}
JSON 内のその他のオブジェクトは正常にデコードされ、ドキュメント内のどこかに複数のアカウント/ユーザー スタイル オブジェクトが埋め込まれている可能性があります。
例えば:
{
"version": "1.0",
"users": [{"type": "user", "username": "jane", "email": "jane@example.com"}],
"extra": {"paid": true, "account": {"type": "account", "account_id": "1234"}}
}
Python では、オブジェクトのインスタンス化方法を制御できるカスタム デコーダーを指定できます。
class CustomJSONDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
kwargs['object_hook'] = self.dict_to_object
super(CustomJSONDecoder, self).__init__(*args, **kwargs)
def dict_to_object(self, data):
identifier = data.get('type')
if identifier == 'account':
return Account(data)
elif identifier == 'user':
return User(data)
return data
def loads(content):
return json.loads(content, cls=CustomJSONDecoder)
同様にJavascriptでこれを行うことができます...
function decoder(key, val) {
if (val._type === "account") {
return Account(val);
} else if (val._type === "user") {
return User(val);
}
return val;
}
function loads(content) {
return JSON.parse(content, decoder);
}
Ruby で同じことを実現する最も簡単な方法はわかりません。
JSON.parse
パラメータを取るのを見てきましたobject_class
が、それは動的に決定されるのではなく、固定されたクラスです。
解析された JSON の後処理によって最終結果が得られるか、解析段階で発生するかはあまり気にしません。最も簡単な方法は、JSON を通常どおりに解析してから、結果のデータ構造を調べて変更することかもしれませんが、その場合でも、それを実装するためのガイダンスをいただければ幸いです。