2
votes

Schéma JSON pour exiger qu'une valeur ne soit PAS présente

Je souhaite effectuer une validation JSON sur mon schéma, qui a quatre propriétés:

  • group
  • partition
  • select
  • fonctionnalités

Si vous utilisez un groupe ou une partition , alors des fonctionnalités sont requises. Si vous utilisez sélectionnez , alors les fonctionnalités sont interdites . (Notez que cela semble être un cas différent que dans cette question - Je ne veux pas faire de fonctionnalités " non obligatoires ", mais faites-le ainsi si vous incluez c'est une erreur de validation.

Mes trois options sont donc:

  • groupe ET fonctionnalités
  • partition ET fonctionnalités
  • sélectionnez ET PAS features

Je les ai encodés comme suit:

"oneOf": [
  { "required": [ "group", "features" ] },
  { "required": [ "partition", "features" ] },
  { "required": [ "select" ] }
]

Mais je n'arrive pas à comprendre comment forcer de manière appropriée les fonctionnalités à être exclu de la dernière option - ou est-ce même une possibilité?


1 commentaires

vous pouvez définir plusieurs schémas parmi ceux valides et placer additionalProperties sur false


3 Réponses :


0
votes

Vous pouvez définir plusieurs schémas parmi ceux valides

{
  "type": "object",
  "properties": {
    "select": {"type": "string"}
  },
  "additionalProperties": false
}

et pour select, vous pouvez définir un schéma avec additionalProperties défini sur false, comme ceci

   {
        "anyOf": [
            { "$ref": "#/definitions/group" },
            { "$ref": "#/definitions/partition" },
            { "$ref": "#/definitions/select" },
        ]
    }

Ensuite, vous obtenez une erreur comme celle-ci:

ValidationError: les propriétés supplémentaires ne sont pas autorisées


4 commentaires

Je ne suis pas un expert, mais la fin de cette section json-schema .org / Understanding-json-schema / reference /… indique que "additionalProperties" nécessite que "properties" soit défini au niveau supérieur de l'objet, et ne fonctionne pas lorsque "properties" est au plus profond d'un "anyOf" ". Suis-je mal compris?


Par «article», vouliez-vous dire «articles»? L'OP ne parle pas d'un tableau, alors pourquoi est-ce là? Toutes mes excuses si je ne comprends que mal.


Par élément, je veux dire tout objet nommé, que nous décrivons dans le schéma, vous pouvez supprimer en toute sécurité le wrapper d'élément si vous décrivez un seul objet.


Merci! De plus, j'ai essayé votre solution et cela fonctionne pour moi, donc mon premier commentaire est clairement erroné. Merci d'avoir répondu! :-)



3
votes

Il existe plusieurs façons de modéliser cela. Si vous voulez avoir la liberté d'autoriser des propriétés supplémentaires, tout en excluant explicitement uniquement une propriété appelée "features", vous pouvez utiliser le mot-clé not :

"oneOf": [
  { "required": [ "group", "features" ] },
  { "required": [ "partition", "features" ] },
  { "required": [ "select" ], "not": { "required": ["features"] } }
]

Le not mot-clé est évalué comme "valide" si le sous-schéma n'est pas valide, et évalué comme "non valide" si le sous-schéma est valide.


3 commentaires

Au moins dans Visual Studio, utiliser pas de cette manière me permet toujours d'utiliser à la fois les fonctionnalités select et . Je veux pouvoir inclure d'autres propriétés, mais explicitement pas les fonctionnalités .


Je ne suis pas un expert, mais utiliser «pas» avec «requis» comme celui-ci n'empêche pas les documents de contenir des «caractéristiques» - il n'est tout simplement pas nécessaire que les documents contiennent des «caractéristiques».


Vous avez mal compris les spécifications. La règle not réussit lorsque la sous-règle échoue et vice versa. La règle requise réussit si la propriété existe et échoue si ce n'est pas le cas; not with required réussit si la propriété est manquante et échoue si elle existe.



0
votes

Une astuce est proposée dans une réponse non acceptée à cette question connexe , qui implique l'utilisation de " not ": {} . Autrement dit, dans le cas où une propriété est présente, ne peut satisfaire aucun schéma. Ainsi, il ne peut pas être présent.

{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "oneOf": [
        {
            "properties": {
                "group": {
                    "type": "string"
                },
                "features": {
                    "type": "string"
                }
            },
            "required": [
                "group",
                "features"
            ]
        },
        {
            "properties": {
                "partition": {
                    "type": "string"
                },
                "features": {
                    "type": "string"
                }
            },
            "required": [
                "partition",
                "features"
            ]
        },
        {
            "properties": {
                "select": {
                    "type": "string"
                },
                "features": {
                    "not": {}
                }
            },
            "required": [
                "select"
            ]
        }
    ]
}


1 commentaires

@JonathanHartley. Oui, pourquoi? Cela résout la question.