我正试图获得" oneof"允许根项目中的选项,但无法找到一个示例,我尝试给出一个错误。 如果它在另一个项目下但不在根目录下,我可以让它工作{' s
示例 - 具有必填字段(jobNum,收款人,金额,类型)和付款类型选项(checkInfo或dollarAmt)的工作付款。我知道这可以通过其他方式完成,但我需要这种方法来实现更复杂的模式。
{
"jobNum": "x216",
"payee": "John Doe",
"type": "check",
"amount": "112.25",
"checkInfo": {
"number": "386"
}
}
{
"JobNum": "x216",
"Payee": "John Doe",
"type" : "Cash",
"amount" : "112.25",
"cashInfo" : {
"dollarAmt" : "112",
"coinAmt" : "0.25"
}
}
以下内容给出了我的错误 - "在读取' oneOf'的值时遇到了意外的令牌。预期的StartObject,Boolean,得到了StartArray"
{
"description": "Job Payment",
"type": "object",
"required": [ "jobNum", "payee", "amount", "type"],
"properties": {
"jobNum": {
"type": "string"
},
"payee": {
"type": "string"
},
"amount": {
"type": "string"
},
"type": {"enum": [ "check", "cash" ]
},
"oneOf": [
{ "$ref": "#/definitions/ptCash" },
{ "$ref": "#/definitions/ptCheck" }
]
},
"definitions": {
"ptCash": {
"properties": {
"checkInfo": {
"number": "string"
}
},
"required": [ "checkInfo" ],
"additionalProperties": false
},
"ptCheck": {
"properties": {
"dollarAmt": {
"type": "string"
},
"coinAmt": {
"type": "string"
}
},
"required": [ "dollarAmt", "coinAmt" ],
"additionalProperties": false
}
},
"additionalProperties": false
}
答案 0 :(得分:2)
您的架构存在一些问题。我在下面为你修好了。我不会解释我所做的所有更改,因为我认为通过阅读架构非常清楚。如果您想了解更多关于任何事情的详细信息,请询问,我将更新答案并提供更多详细信息。
oneOf
关键字只能出现在架构中。 properties
关键字是一个对象,其值为模式。当您将“oneOf”直接放在properties
下时,它不会被解释为关键字,它会被解释为名为“oneOf”的属性。然后验证器会抱怨,因为属性“oneOf”的值应该是一个模式,而不是像oneOf
关键字那样的模式数组。
您对additionalProperties
的使用不起作用。这个关键字不像人们通常认为的那样有效。 JSON Schema关键字不知道它们所在模式之外的任何状态。让我们先看看oneOf
的“ptCheck”分支。这描述了属性“数字”,表示它是必需的,并且可能没有“数字”以外的关键字。然后您的顶级定义属性“jobNum”,“payee”,“amount”和“type”,需要它们all并且不允许其他属性。这两件事永远不可能同时存在。即使您的架构有效,也没有对该架构有效的JSON值。这就是为什么我将“checkInfo”和“cashInfo”的定义移到顶层,只将required
部分放在oneOf
中。这种方法的唯一缺点是你可以传递“checkInfo”和“cachInfo”对象,它将验证。外来属性被忽略。有很多方法,但它们有问题,我不建议使用它们。
我总是建议人们不要使用"additionalProperties": false
而忽略未知属性。原因是JSON Schema是一个约束系统。任何有效的JSON对空模式({}
)都有效,并且模式中的每个关键字都会添加一些约束。这是人们在定义类时习惯的不同方法。空类不描述任何内容,并添加有效值。我们使用"additionalProperties": false
来使JSON Schema更像是定义一个类,但是试图让JSON Schema表现得像它不会引起像你在这里看到的那样的挑战。
{
"description": "Job Payment",
"type": "object",
"required": ["jobNum", "payee", "amount", "type"],
"properties": {
"jobNum": { "type": "string" },
"payee": { "type": "string" },
"amount": { "type": "string" },
"type": { "enum": ["check", "cash"] },
"checkInfo": {
"type": "object",
"properties": {
"number": { "type": "string" }
},
"required": ["number"]
},
"cashInfo": {
"type": "object",
"properties": {
"dollarAmt": { "type": "string" },
"coinAmt": { "type": "string" }
},
"required": ["dollarAmt", "coinAmt"]
}
},
"oneOf": [
{ "$ref": "#/definitions/ptCash" },
{ "$ref": "#/definitions/ptCheck" }
],
"definitions": {
"ptCheck": {
"type": "object",
"properties": {
"type": { "enum": ["check"] }
},
"required": ["checkInfo"]
},
"ptCash": {
"type": "object",
"properties": {
"type": { "enum": ["cash"] }
},
"required": ["cashInfo"]
}
},
"additionalProperties": false
}
答案 1 :(得分:1)
oneOf
应放在prope中ptCash
重新编写ptCheck
和type: object
的规则以下架构应与ptCheck
:
{
"description": "Job Payment",
"type": "object",
"required": [ "jobNum", "payee", "amount", "type"],
"properties": {
"jobNum": {
"type": "string"
},
"payee": {
"type": "string"
},
"amount": {
"type": "string"
},
"type": {"enum": [ "check", "cash" ]
}
},
"oneOf": [
{ "$ref": "#/definitions/ptCash" },
{ "$ref": "#/definitions/ptCheck" }
],
"definitions": {
"ptCash": {
"properties": {
"checkInfo": {
"type": "object",
"required": ["number"],
"properties": {
"number": {
"type": "string"
}
}
}
},
"required": [ "checkInfo" ]
},
"ptCheck": {
"properties": {
"cashInfo": {
"type": "object",
"properties": {
"dollarAmt": {
"type": "string"
},
"coinAmt": {
"type": "string"
}
},
"required": ["dollarAmt", "coinAmt"]
}
},
"required": ["cashInfo"]
}
}
}
提供如下示例:
import jsonschema
import simplejson as json
schema_filename = '47926398.json'
with open(schema_filename, 'r') as f:
schema_data = f.read()
schema = json.loads(schema_data)
# validate with checkInfo
json_obj = {
"jobNum": "x216",
"payee": "John Doe",
"type": "check",
"amount": "112.25",
"checkInfo": {
"number": "386"
}
}
jsonschema.validate(json_obj, schema)
# invalidate
json_obj = {
"jobNum": "x216",
"payee": "John Doe",
"type": "check",
"amount": "112.25",
"checkInfox": {
"number": "386"
}
}
jsonschema.validate(json_obj, schema)
# validate with cashInfo
json_obj = {
"jobNum": "x216",
"payee": "John Doe",
"type": "check",
"amount": "112.25",
"cashInfo": {
"dollarAmt": "400",
"coinAmt": "30"
}
}
jsonschema.validate(json_obj, schema)
# invalidate with cashInfo
json_obj = {
"jobNum": "x216",
"payee": "John Doe",
"type": "check",
"amount": "112.25",
"cashInfox": {
"dollarAmt": "400",
"coinAmt": "30"
}
}
jsonschema.validate(json_obj, schema)
# invalidate with cashInfo.dollarAmtx
json_obj = {
"jobNum": "x216",
"payee": "John Doe",
"type": "check",
"amount": "112.25",
"cashInfo": {
"dollarAmtx": "400",
"coinAmt": "30"
}
}
jsonschema.validate(json_obj, schema)