The xsi:type
attribute is intended to be used when you have a hierarchy of named types in a schema and an element whose declared type is the base type but whose actual type is one of the derived types. The archetypal example would be an address
type with subtypes usAddress
and ukAddress
In your schema the FieldValidator
and Next
elements are declared using anonymous nested <complexType>
definitions rather than named types, so there's no way you could have other types derived from these, so no sense in using xsi:type
. I would structure the schema differently, using top-level named types:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="FieldValidatorType">
<xs:sequence>
<xs:element name="Next" type="FieldValidatorType" minOccurs="0" />
</xs:sequence>
<xs:attribute name="PropertyName" type="xs:string" use="optional" />
</xs:complexType>
<xs:complexType name="RequiredFieldValidator">
<xs:complexContent>
<xs:extension base="FieldValidatorType" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="AsciiValidator">
<xs:complexContent>
<xs:extension base="FieldValidatorType" />
</xs:complexContent>
</xs:complexType>
<xs:complexType name="StringLengthValidator">
<xs:complexContent>
<xs:extension base="FieldValidatorType">
<xs:attribute type="xs:byte" name="MaxLength" use="optional"/>
<xs:attribute type="xs:byte" name="MinLength" use="optional"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- and similar complexType declarations for the other types such as
AlphaValidator -->
<xs:element name="ValidatorList">
<xs:complexType>
<xs:sequence>
<!-- define the FieldValidator element by referring to the base
FieldValidatorType, instance documents can use xsi:type to
substitute subtypes such as StringLengthValidator -->
<xs:element name="FieldValidator" maxOccurs="unbounded" minOccurs="0"
type="FieldValidatorType" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
As well as making the xsi:type
attributes work properly, this has the advantage of tying the different facets to their respective validator types (e.g. MaxLength
is only valid for a StringLengthValidator
) and also supporting arbitrary depths of Next
nesting (because the type definition is recursive).