Как получить схему для конкретного значения JSON? - PullRequest
1 голос
/ 03 июля 2019

Как все мы знаем, на языке oop мы можем знать тип экземпляра и тип свойств экземпляра.

Я считаю, что значение JSON похоже на экземпляр схемы JSON.Так есть ли какое-либо решение для получения подсхемы для каждого значения JSON?

Например, у меня под рукой есть и схема JSON, и экземпляр JSON, как показано ниже:

{
    'definitions': {
        'img': {
            'type': 'object',
            'properties': {
                'url': {
                    'type': 'string'
                }
            }
        }
    },
    'type': 'object',
    'properties': {
        'name': {
            'type':'string'
        },
        'avatar': {
            '$ref': '#/definitions/img'
        }
    }
}

И экземпляр JSON:

var json =
{
  'name': 'James',
  'avatar': {'url':'http://xxxx.jpg'}
}

Как я могу получить тип аватара "img" при программном доступе к json.avatar?

Кстати, я использую схему JSON.Net.

1 Ответ

0 голосов
/ 12 июля 2019

При попытке решить эту проблему важно знать, где и как Jschema хранит определения, и что вы можете перемещаться по схеме аналогично JObject.

Итак, при условии, что вы загрузили схему следующим образом (используя Newtonsoft):

var schema = JSchema.Parse(@"{
                    'definitions': {
                        'img': {
                            'type': 'object',
                            'properties': {
                                'url': {
                                    'type': 'string'
                                }
                            }
                        }
                    },
                    'type': 'object',
                    'properties': {
                        'name': {
                            'type':'string'
                        },
                        'avatar': {
                            '$ref': '#/definitions/img'
                        }
                    }
                }");

при доступе к avatar свойству схемы вы фактически получите уже замененную ссылку с определением (так как Jschema заменяет ее во время синтаксического анализа). Но само определение не потеряно, а хранится в schema.ExtensionData["definitions"] - что для меня было неожиданностью в начале - и вы можете получить доступ к этим определениям, как к стандартным объектам JObjects.

При определенных условиях (например, имея одно определение с url токеном) вы можете получить доступ к фактическому типу определения:

        var avatarKey = schema.Properties["avatar"].Properties.Keys.Single(); //'url'
        var definitions = schema.ExtensionData["definitions"]; 

Затем получите определение, содержащее url и получите корневое имя ( img в вашем сценарии):

        var matching = definitions.SelectTokens($"..{avatarKey}");
        var avatarDefinition = matching.Single().Root;
        var avatarType = (avatarDefinition.First() as JProperty).Name; //'img'

Это не универсальное решение для каждой схемы, но на его основе вы можете настроить его для более сложных потребностей.

...