例如,文件系统的模式,目录包含文件列表 . 该模式包括文件的规范,接下来是子类型“图像”和另一个“文本” .
底部有主目录模式 . 目录具有属性内容,该属性内容是应该是文件的子类型的项目数组 .
基本上我正在寻找的是一种告诉验证器从被验证的json对象中的属性中查找“$ ref”的值的方法 .
Example 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
}
]
}
The "pseudo" Schema 请注意"image"和"text"定义包含在同一模式中,但它们可能在其他地方定义
{
"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
]
}
}
}
}
2 回答
单独的JSON Schema的验证部分不能这样做 - 它代表一个固定的结构 . 您想要的是在验证时解析/引用模式 .
但是,您可以使用JSON Hyper-Schema和
rel="describedby"
链接表达此信息:所以在这里,它从
"fileType"
获取值并使用它来计算关系"describedby"的链接 - 这意味着"the schema at this location also describes the current data" .问题是大多数验证者都没有注意到任何链接(包括“由”描述的链接) . 你需要找到一个“超验证器” .
UPDATE :tv4库已添加此功能
我认为cloudfeet的答案是一个有效的解决方案 . 您也可以使用相同的方法described here .
您将拥有一个文件对象类型,它可以是“anyOf”您要定义的所有子类型 . 您将使用枚举,以便能够引用和验证每个子类型 .
如果子类型模式在同一个Json-Schema文件中,则不需要使用“$ ref”显式引用uri . 正确的draft4验证器将找到枚举值,并将尝试验证Json-Schema树中的“subschema” .
在draft5(正在进行中)已经提出了一个"switch"语句,它将允许以更明确的方式表达替代方案 .