user2432281
user2432281

Reputation: 71

How to add conditional validation in XSD :

Existing XSD Snippet:

<xs:element name="searchcriteria">
   <xs:complexType>
     <xs:sequence>  
       <xs:element ref="filter" 
                   minOccurs="0" 
                   maxOccurs="unbounded" />
     </xs:sequence>
     <xs:attribute name="Request" 
                   type="RequestType" />
   </xs:complexType>
 </xs:element>  


<xs:element name="filter">
   <xs:complexType>
     <xs:sequence>
       <xs:element ref="filter" 
                   minOccurs="0" 
                   maxOccurs="unbounded" />
     </xs:sequence>
     <xs:attribute name="FieldName" 
                   type="FieldNameType" />
    </xs:complexType>
 </xs:element>

...

Now i want to modify this XSD to provide a validation that :

  1. When RequestType = R1, Then Alowed Fields names are F1 and F2
  2. When Request Type = R2, Then allowed Fields names are F1, F3 and F4. ( May be a new enumeration is required)

How can i add such validations ? Thanks.

Upvotes: 7

Views: 15786

Answers (1)

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

Reputation: 25054

The basic idea of XSD (and most other XML schema languages) is to bind validation behavior to element types. If you want one set of instances validated one way and another set of instances validated another way (goes the idea), it's prima facie evidence that they are actually two distinct types of elements, and should have two distinct names.

So the simplest way to make XSD validate your requests as you describe is to replace your searchcriteria element with a pair of elements named R1 and R2. Declare them with different types, as you wish: either they each have an element named filter with an attribute carrying an appropriate enumerated type, or R1 is declared as having either an F1 or an F2 as a child, and R2 is declared as having a choice of F1, F3, or F4.

If you can't or won't do this, you can use XSD 1.1 and its conditional type assignment feature to declare two types for searchcriteria (the two types you would otherwise have used for R1 and R2) and assign the appropriate type based on the value of the Request attribute. You can also use assertions on searchcriteria to check the co-constraint.

If you don't have access to an XSD 1.1 validator, tell the vendor of your XSD 1.0 validator that you'd like an upgrade, and explore the use of Schematron assertions to check the constraint.

See also this essentially similar question for more concrete discussion of the options, with examples.

Upvotes: 8

Related Questions