validation of json schema having oneOf keyword

2019-07-30 03:38发布

问题:

I have the following json schema for my web app.

{  
  "type":"object",
    "properties": {
     "person_identifier":{
        "type":"object",
        "oneOf":[
               {"$ref":"#/person_identifier/rememberme_id"},
               {"$ref":"#/person_identifier/email"},
               {"$ref":"#/person_identifier/account_number"}
        ],
        "email":{
            "type":"string"
        },
        "rememberme_id":{
            "type":"string"
        },
        "account_number":{
            "type":"string"
        }    
       }
    }
}

My goal is to accept only one of the three "person_identifier"-email, rememberme_id or account_number in the api request to my application. I am not able to validate that the above schema will enforce the required constraints. I have tried validating on jsfiddle.com but it shows that my schema is not validating input correctly. Here is my code for validation on jsfiddle.com:

var data, schema;

schema = {  
     person_identifier:{
           type:'object',
           'oneOf':[
               {$ref:'#/person_identifier/rememberme_id'},
               {$ref:'#/person_identifier/email'},
               {$ref:'#/person_identifier/buyer_account_number'}
           ],
        'email':{
            type:'string'
        },
        'rememberme_id':{
            type:'string'
        },
        'account_number':{
            type:'string'
        }    
       }
};

data = {
  person_identifier: {
    email: 'abc@abc.com',
    rememberme_id: '1345'
  }
};

alert('Validation: ' + tv4.validate(data, schema, true));

For example, jsfiddle validates the data as correctly satisfying the schema when it should not. Only one input identifier should be allowed. I have referred almost all available questions and documentation on using oneOf. Any pointers as to what I am doing incorrectly? Thank you.

回答1:

Using http://geraintluff.github.io/tv4/try/ I was able to formulate two answers for my question. Here are the links: Answer1 and Answer2

The schema in my question was incorrect. The schema meant match oneOf(all three references), email, rememberme_id, buyer_account_number. The data (email and rememberme_id) matched email and rememberme_id sub-resources (individually) of person_identifier. They were present separate along with the oneOf keyword, so the oneOf never worked.

Using simple explanation from http://www.asbjornenge.com/wwc/json_schema.html I understood my mistake. For complex oneOf examples, unlike the one mentioned in the previous link, we can use a common "property" in all sub-schemas intended to be restricted by the oneOf keyword ("identifierType" in the answer links I have posted above). It is crucial to have this common yet differentiating factor which makes oneOf work. Also, the sub-schemas in oneOf that we refer to should be present entirely inside the oneOf array(Answer2) or be passed as a reference(Answer1). They cannot be comma separated along with oneOf as it defeats the purpose (the mistake which I was making). I referred the answer by @cloudfeet to this question.

Hope this helps.