Question

I need xml to match XSD schema but it doesnt match. What can be wrong in XSD schema? Something not right with xsi:type="...". I may miss something. Hope you can notice what is wrong. I have been trying to use xsd validate online and fix it but doesnt work. So I give up and decide to write here. Your help much appreciated. Thanks!

Here is XML:

<?xml version="1.0" encoding="utf-8" ?>
<ValidatorList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <FieldValidator xsi:type="RequiredFieldValidator"  PropertyName="BankTransactionNumber">
   <Next xsi:type="AsciiValidator" />
  </FieldValidator>
  <FieldValidator xsi:type="RequiredFieldValidator"  PropertyName="CurrencyIndicator">
   <Next xsi:type="StringLengthValidator" MaxLength="3" MinLength="3">
   <Next xsi:type="AlphaValidator" />
  </Next>
 </FieldValidator>
</ValidatorList>

XSD Schema for this XML:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ValidatorList">
<xs:complexType>
  <xs:sequence>
    <xs:element name="FieldValidator" maxOccurs="unbounded" minOccurs="0">
      <xs:complexType mixed="true">
        <xs:sequence>
          <xs:element name="Next" minOccurs="0">
            <xs:complexType mixed="true">
              <xs:sequence>
                <xs:element name="Next" minOccurs="0">
                  <xs:complexType mixed="true">
                    <xs:sequence>
                      <xs:element name="Next" minOccurs="0">
                        <xs:complexType>
                          <xs:simpleContent>
                            <xs:extension base="xs:string">
                              <xs:attribute type="xs:byte" name="DecimalPlaces"/>
                            </xs:extension>
                          </xs:simpleContent>
                        </xs:complexType>
                      </xs:element>
                    </xs:sequence>
                    <xs:attribute type="xs:byte" name="MaxLength" use="optional"/>
                    <xs:attribute type="xs:byte" name="MinLength" use="optional"/>
                    <xs:attribute type="xs:string" name="AllowedValues" use="optional"/>
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
              <xs:attribute type="xs:byte" name="MaxLength" use="optional"/>
              <xs:attribute type="xs:byte" name="MinLength" use="optional"/>
              <xs:attribute type="xs:byte" name="DefaultValue" use="optional"/>
            </xs:complexType>
          </xs:element>
          <xs:element type="xs:string" name="RegEx" minOccurs="0"/>
        </xs:sequence>
        <xs:attribute type="xs:string" name="PropertyName" use="optional"/>
        <xs:attribute type="xs:byte" name="DefaultValue" use="optional"/>
        <xs:attribute type="xs:string" name="TypeProperty" use="optional"/>
        <xs:attribute type="xs:string" name="Regex" use="optional"/>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

I got error message like this:

Error - Line 4, 39: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 39; cvc-elt.4.2: Cannot resolve 'AsciiValidator' to a type definition for element 'Next'.
Error - Line 6, 87: org.xml.sax.SAXParseException; lineNumber: 6; columnNumber: 87; cvc-elt.4.2: Cannot resolve 'RequiredFieldValidator' to a type definition for element 'FieldValidator'.
Error - Line 7, 72: org.xml.sax.SAXParseException; lineNumber: 7; columnNumber: 72; cvc-elt.4.2: Cannot resolve 'StringLengthValidator' to a type definition for element 'Next'.
Error - Line 8, 41: org.xml.sax.SAXParseException; lineNumber: 8; columnNumber: 41; cvc-elt.4.2: Cannot resolve 'AlphaValidator' to a type definition for element 'Next'.
Was it helpful?

Solution

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).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top