web-dev-qa-db-fra.com

Comment (si possible) définir dans le schéma JSON une propriété d’éléments de tableau doit être unique?

Étant donné le schéma JSON suivant, il est possible d'indiquer que la propriété "name" doit être unique (c'est-à-dire qu'il ne devrait PAS y avoir deux éléments avec le même "nom" dans le tableau "elements".

{
    "root":{
        "type":"object",
        "properties": {
            "elements": {
                "type":"array",
                "minItems": 1,
                "items":{
                    "type":"object",
                    "properties":{
                        "name": {
                            "type":"string",
                            "title":"Element Name",
                            "minLength":3,
                        },
                        "url": {
                            "type":"string",
                            "title":"Some URL"
                        }
                    }
                }
            }
        }
    }
}

J'ai essayé d'utiliser le mot clé uniqueItems mais il semble qu'il ait été conçu pour de simples listes de valeurs.

20
begie

Non ce n'est pas possible. A partir de la docs, json-schema: ... un format basé sur JSON pour définir la structure des données JSON.

Il est assez limité pour valider des valeurs de données car ce n'est pas le but de la norme. Beaucoup de gens ont déjà posé cette question parce qu'il est courant de demander une sorte de "caractéristique unique". Malheureusement pour ceux qui en ont besoin, json-schema ne vous fournit pas cela.

Donc, si vous voulez vous assurer l'unicité, votre seule option est d'avoir "nom" comme clé de propriété plutôt que comme valeur de propriété.

20
jruizaranguren

Si le refactoring de la structure de données est une option, l'approche suivante peut être utile:

  • Remplacez le tableau par une carte. Ceci peut être facilement réalisé en utilisant un objet avec patternProperties. Le motif est une expression régulière. Tout objet correspondant au modèle sera validé par rapport au schéma de la propriété de modèle. Un modèle correspondant à toute chaîne> = 3 caractères ressemble à ceci: "....*", mais il semble qu'un ".*" final soit toujours impliqué, donc "..." fonctionne également.
  • L'ajout de additionalProperties: false est une étape supplémentaire pour appliquer votre contrainte (minLength:3).
  • Pour appliquer au moins un élément de votre carte (vous utilisiez minItems:1 pour votre tableau), remplacez minItems par minProperties.

... résultant dans le schéma ci-dessous:

"root": {
  "type": "object", 
  "properties": {
    "elements": {
      "type": "object", 
      "patternProperties": {
        "...": {
          "type": "object", 
          "properties": {
            "url": {
              "type": "string"
            }
          }
        }
      }, 
      "additionalProperties": false, 
      "minProperties": 1
    }
  }
}

Si un document comme celui-ci (extrait) correspond à votre ancien schéma,

"elements": [
  {
    "name": "abc", 
    "url": "http://myurl1"
  }, 
  {
    "name": "def", 
    "url": "http://myurl2"
  }, 
  {
    "name": "ghij", 
    "url": "http://myurlx"
  }
]

... un document comme celui-ci (extrait) correspondra au nouveau schéma:

"elements": {
  "abc": {
    "url": "http://myurl1"
  }, 
  "def": {
    "url": "http://myurl2"
  }, 
  "ghij": {
    "url": "http://myurlx"
  }
}
6
yaccob

Si votre cas d'utilisation peut gérer la surcharge ajoutée, vous pouvez appliquer une transformation sur le document pour générer un document réduit, puis appliquer à nouveau la validation avec un mini-schéma distinct sur le document réduit.

Voici quelques liens avec des informations sur les outils de transformation Json:

Le traitement de votre exemple de cas serait très simple dans JSONata.

0
Basel Shishani