例如,文件系统的模式,目录包含文件列表。该模式包括文件的规范,接下来是子类型“图像”和另一个“文本”。
在底部有主目录架构。目录具有属性内容,该属性内容是应该是文件的子类型的项目数组。
基本上我正在寻找的是一种告诉验证器从被验证的json对象中的属性中查找“$ ref”的值的方法。
示例json:
{
"name":"A directory",
"content":[
{
"fileType":"http://x.y.z/fs-schema.json#definitions/image",
"name":"an-image.png",
"width":1024,
"height":800
}
{
"fileType":"http://x.y.z/fs-schema.json#definitions/text",
"name":"readme.txt",
"lineCount":101
}
{
"fileType":"http://x.y.z/extended-fs-schema-video.json",
"name":"demo.mp4",
"hd":true
}
]
}
“伪”架构请注意,“图像”和“文本”定义包含在同一架构中,但它们可能在其他地方定义
{
"id": "http://x.y.z/fs-schema.json",
"definitions": {
"file": {
"type": "object",
"properties": {
"name": { "type": "string" },
"fileType": {
"type": "string",
"format": "uri"
}
}
},
"image": {
"allOf": [
{ "$ref": "#definitions/file" },
{
"properties": {
"width": { "type": "integer" },
"height": { "type": "integer"}
}
}
]
},
"text": {
"allOf": [
{ "$ref": "#definitions/file" },
{ "properties": { "lineCount": { "type": "integer"}}}
]
}
},
"type": "object",
"properties": {
"name": { "type": "string"},
"content": {
"type": "array",
"items": {
"allOf": [
{ "$ref": "#definitions/file" },
{ *"$refFromProperty"*: "fileType" } // the magic thing
]
}
}
}
}
答案 0 :(得分:10)
单独的JSON Schema的验证部分不能这样做 - 它代表一个固定的结构。您想要的是在验证 -time
时解析/引用模式但是,您可以使用JSON Hyper-Schema和rel="describedby"
链接表达这一点:
{
"title": "Directory entry",
"type": "object",
"properties": {
"fileType": {"type": "string", "format": "uri"}
},
"links": [{
"rel": "describedby",
"href": "{+fileType}"
}]
}
所以在这里,它从"fileType"
获取值并使用它来计算具有关系的链接“describeby” - 这意味着“此位置的模式也描述了当前数据”。
问题是大多数验证者都没有注意到任何链接(包括“由”描述的链接)。你需要找到一个“超验证器”。
更新 :tv4库已添加此功能
答案 1 :(得分:3)
我认为cloudfeet答案是一种有效的解决方案。您也可以使用相同的方法described here。
您将拥有一个文件对象类型,可以是“anyOf”您要定义的所有子类型。您将使用枚举,以便能够引用和验证每个子类型。
如果子类型模式在同一个Json-Schema文件中,则不需要使用“$ ref”显式引用uri。正确的draft4验证器将找到枚举值,并将尝试验证Json-Schema树中的“subschema”。
在draft5(进行中)中,已经提出了一个“切换”声明,它将允许以更明确的方式表达替代方案。