/ / JSON-Schema oneOf pour l'option sous la zone racine - json, jsonschema

JSON-Schema oneOf pour une option sous la zone racine - json, jsonschema

J'essaye d'obtenir le "oneof" pour permettre des options dans les éléments racine mais ne peux pas trouver un exemple et ce que j'essaye donne une erreur. Je peux le faire fonctionner s'il se trouve sous un autre élément mais pas sous la racine {"s

Exemple - un paiement de tâche comportant des champs obligatoires(jobNum, bénéficiaire, montant, type,) et une option pour le type de paiement (checkInfo ou dollarAmt). Je sais que cela pourrait être fait d'autres façons, mais j'ai besoin de cette méthode pour un schéma plus complexe.

{
"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"
}
}

Ce qui suit me donne cette erreur - "Jeton inattendu rencontré lors de la lecture de la valeur pour" oneOf ". Expected StartObject, Boolean, got 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
}

Réponses:

1 pour la réponse № 1
  1. oneOf devrait être placé en prope
  2. Vous devez réécrire la règle pour les deux ptCash et ptCheck en utilisant type: object

Le schéma suivant devrait fonctionner avec 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"]
}
}
}

Donnez un exemple comme ci-dessous:

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)

2 pour la réponse № 2

Il y a quelques problèmes avec votre schéma. Je l'ai corrigé pour vous ci-dessous. Je ne vais pas expliquer toutes les modifications que j'ai apportées parce que je pense que c'est surtout assez clair en lisant le schéma. Si vous voulez plus de détails sur quoi que ce soit, il suffit de demander et je mettrai à jour la réponse avec plus de détails.

le oneOf Le mot clé ne peut apparaître que dans un schéma. le properties mot-clé est un objet dont les valeurs sont des schémas. Lorsque vous mettez "oneOf" directement sous properties, ce n'est pas interprété comme un mot clé, c'estinterprété comme une propriété appelée "oneOf". Le validateur se plaint alors parce que la valeur de la propriété "oneOf" devrait être un schéma, pas un tableau de schémas comme le oneOf mot-clé.

Votre utilisation de additionalProperties ne fonctionne pas. Ce mot-clé ne fonctionne pas comme les gens le supposent souvent. Les mots-clés du schéma JSON ne connaissent aucun état en dehors du schéma dans lequel ils se trouvent. Examinons la branche "ptCheck" de votre oneOf première. Ceci décrit la propriété "nombre", indique qu'elle est obligatoire et qu'il ne peut y avoir aucun mot clé autre que "numéro". Ensuite, votre niveau supérieur définit les propriétés "jobNum", "payee", "amount" et "type", les requiert toutes et n'autorise aucune autre propriété. Ces deux choses ne peuvent jamais être vraies en même temps. Même si votre schéma est valide, aucune valeur JSON ne peut jamais être valide par rapport à ce schéma. C’est pourquoi j’ai déplacé les définitions de «checkInfo» et «cashInfo» au niveau supérieur et n’a mis required part à oneOf. Le seul inconvénient de cette approche est que vouspeut passer à la fois un objet "checkInfo" et un objet "cachInfo" et il sera validé. La propriété étrangère est ignorée. Il existe des moyens de contourner cela, mais ils sont suffisamment problématiques pour que je ne conseille pas de les utiliser.

Je conseille toujours aux gens de ne pas utiliser "additionalProperties": false et d'ignorer les propriétés inconnues à la place. La raison en est que le schéma JSON est un système de contraintes. Tout JSON valide est valide par rapport au schéma vide ({}) et chaque mot clé du schéma ajoutecontrainte. Il s'agit d'une approche différente de ce à quoi les gens sont habitués lors de la définition des classes. Une classe vide ne décrit rien et des valeurs valides sont ajoutées. Nous utilisons "additionalProperties": false pour que le schéma JSON se comporte plus comme définir une classe, mais essayer de faire en sorte que le schéma JSON se comporte comme quelque chose, cela ne pose pas de problèmes comme celui que vous voyez ici.


{
"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
}