众所周知,用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'}
}
当我以编程方式访问json.avatar时,如何获得化身的类型为“ img”?
顺便说一句,我正在使用JSON.Net Schema。
答案 0 :(得分:0)
尝试解决此问题时,重要的一件事是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'
这不是每种模式的通用解决方案,但是您可以基于此解决方案将其调整为更复杂的需求。