希望我能在这个验证问题上找到一些帮助:我有一个JSON数组,可以有多种对象类型(视频、图像)。在该数组中,对象具有rel
字段值。我正在处理的情况是,只能有一个对象具有“rel”:“primaryMedia”
允许-视频或图像。
以下是图像和视频案例的对象表示,都显示了“rel”:“primaryMedia”
。
{
"media": [
{
"caption": "Caption goes here",
"id": "ncim87659842",
"rel": "primaryMedia",
"type": "image"
},
{
"description": "Shaima Swileh arrived in San Francisco after fighting for 17 months to get a waiver from the U.S. government to be allowed into the country to visit her son.",
"headline": "Yemeni mother arrives in U.S. to be with dying 2-year-old son",
"id": "mmvo1402810947621",
"rel": "primaryMedia",
"type": "video"
}
]
}
下面是我创建的模式的精简版本,我使用的之一验证了这一点(假设这可以处理我的情况)。然而,它并没有像预期的那样工作。
{
"$id": "http://example.com/schema/rockcms/article.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {},
"properties": {
"media": {
"items": {
"oneOf": [
{
"additionalProperties": false,
"properties": {
"caption": {
"type": "string"
},
"id": {
"type": "string"
},
"rel": {
"enum": [
"primaryMedia"
],
"type": "string"
},
"type": {
"enum": [
"image"
],
"type": "string"
}
},
"required": [
"caption",
"id",
"rel",
"type"
],
"type": "object"
},
{
"additionalProperties": false,
"properties": {
"description": {
"type": "string"
},
"headline": {
"type": "string"
},
"id": {
"type": "string"
},
"rel": {
"enum": [
"primaryMedia"
],
"type": "string"
},
"type": {
"enum": [
"video"
],
"type": "string"
}
},
"required": [
"description",
"headline",
"id",
"rel",
"type"
],
"type": "object"
}
]
},
"type": "array"
}
}
}
在以下位置使用JSON模式验证程序:https://www.jsonschemavalidator.net,模式会在正确显示数据时进行验证,但在尝试捕获错误时,模式不起作用。
在下面的例子中,为视频添加了headline
,但缺少id
。这应该会失败,因为视频中不允许出现headline
,并且需要id
。
{
"media": [
{
"headline": "Yemeni mother arrives in U.S. to be with dying 2-year-old son",
"rel": "primaryMedia",
"type": "video"
}
]
}
然而,我从验证器得到的结果并不是完全预期的。它的响应似乎将两个对象模式混为一谈。
除此之外,我还发现该模式将允许在媒体中同时填充视频和图像对象,这是不期望的。
我一直想弄清楚我做错了什么,但我被难住了。如果有人提供反馈,我将非常感谢。提前谢谢!
验证程序响应:
消息:JSON对“oneOf”中的任何架构都无效。架构路径:#/properties/media/items/oneOf
消息:尚未定义属性“headline”,架构不允许其他属性。架构路径:#/properties/media/items/oneOf/0/additionalProperties
消息:枚举中没有定义值“视频”。模式路径:#/属性/媒体/项/oneOf/0/属性/类型/枚举
消息:对象:description,id中缺少必需的属性。架构路径:#/properties/media/items/oneOf/1/Required
消息:对象中缺少必需的属性:标题,id。架构路径:#/properties/media/items/oneOf/0/Required
你的问题由三部分组成,但前两部分是联系在一起的,所以我将解决这些问题,尽管它们本身没有“解决方案”。
您不能使用JSON模式执行此操作。适用于数组的JSON模式关键字集没有表示“其中一个值必须匹配模式”的方法,而是适用于数组中的所有项或数组中的特定项(如果项
是与对象相对的数组)。https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.4
JSON模式规范(从草案7开始)没有为返回错误指定任何格式,但是您得到的错误结构在它告诉您的方面是相当“完整”的(类似于我们为草案8指定应该返回错误的方式)。
考虑一下,验证器在业务逻辑方面对您的架构或JSON实例一无所知。验证JSON实例时,验证器可能会逐步检查所有值,并根据所有适用的子模式测试验证规则。查看您的错误,oneOf
中的两个模式都适用于数组中的所有项,因此所有项都要进行验证测试。如果一个不满足条件,其他的也将进行测试。当使用中的一个时,验证器无法知道您的意图是什么。
您可以通过使用if
/then
组合来绕过此问题。如果您的If
模式只是该类型的常量,而您的then
模式是完整的对象类型,您可能会得到更清晰的错误响应,但我还没有测试这个理论。
从规范。。。
项目
:
如果“items”是一个模式,那么如果数组中的所有元素都成功地根据该模式进行验证,则验证将成功。
one Of
:
如果一个实例成功地针对该关键字值定义的一个架构进行验证,则该实例将成功地针对该关键字进行验证。
你所做的是说:数组中的每一项都应该根据[schemaA]有效。模式:对象应该是有效的,根据这些模式:[oneOf
内的模式]。
当您认为项目必须是以下项目之一时,我可以看出这是多么令人困惑,但是项目
独立地将值模式应用于数组中的每个项目。
要使其符合您的意思,请将项中的
项移到
项上方,然后将其中一种媒体类型重构为另一种媒体项架构。
这里有一个sudo模式。
oneOf: [items: properties: type: const: image], [items: properties: type: image]
如果这些不清楚或者你有任何后续问题,请告诉我。