Hi,

I want to validate an xml which will be in the fol format :

< Root >
<Hierarchy> <!--Optional Tag -->
<Subjects> <!--Optional Tag -->
<Subject>
</Subject>
</Subjects>
<Hierarchy>
</Root>

As stated above the Hierarchy and Subject tag are optional. Following are valid xmls :

<Root><Subject>xyz</Subject></Root>

<Root><Subjects><Subject>xyz</Subject></Subjects></Root>

<Root><Hierarchy><Subjects><Subject>xyz</Subject>
</Subjects></Hierarchy></Root>

Adding minOccurs="0" to Hierarchy/Subjects element does not suffice the requirement since then it doesnot expect Subject element.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="(URL address blocked: See forum rules)">
	<xs:element name="ImportFile">
		<xs:complexType>
			<xs:sequence minOccurs="0" maxOccurs="1">
				<xs:element name="Hierarchy">
					<xs:complexType>
						<xs:sequence minOccurs="0" maxOccurs="1">
							<xs:element name="Subjects">
								<xs:complexType>
									<xs:sequence minOccurs="0" maxOccurs="unbounded">
										<xs:element name="Subject"/>
			                				</xs:sequence>
            				           </xs:complexType>				
			  				</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

Hi,

I want to validate an xml which will be in the fol format :

< Root >
<Hierarchy> <!--Optional Tag -->
<Subjects> <!--Optional Tag -->
<Subject>
</Subject>
</Subjects>
<Hierarchy>
</Root>

As stated above the Hierarchy and Subject tag are optional. Following are valid xmls :

<Root><Subject>xyz</Subject></Root>

<Root><Subjects><Subject>xyz</Subject></Subjects></Root>

<Root><Hierarchy><Subjects><Subject>xyz</Subject>
</Subjects></Hierarchy></Root>

Adding minOccurs="0" to Hierarchy/Subjects element does not suffice the requirement since then it doesnot expect Subject element.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="(URL address blocked: See forum rules)">
	<xs:element name="ImportFile">
		<xs:complexType>
			<xs:sequence minOccurs="0" maxOccurs="1">
				<xs:element name="Hierarchy">
					<xs:complexType>
						<xs:sequence minOccurs="0" maxOccurs="1">
							<xs:element name="Subjects">
								<xs:complexType>
									<xs:sequence minOccurs="0" maxOccurs="unbounded">
										<xs:element name="Subject"/>
			                				</xs:sequence>
            				           </xs:complexType>				
			  				</xs:element>
						</xs:sequence>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

84 views and no reply..
Any ideas/hints will be useful ..

<Root><Subject>xyz</Subject></Root>
<Root><Subjects><Subject>xyz</Subject></Subjects></Root>
<Root><Hierarchy><Subjects><Subject>xyz</Subject></Subjects></Hierarchy></Root>

Adding minOccurs="0" to Hierarchy/Subjects element does not suffice the requirement since then it doesnot expect Subject element.

That's because minOccurs only indicates how many times that element may appear; it doesn't relax any restrictions on the structure of conforming XML documents.

If you want the root element to contain different kinds of elements, you have to say it explicitly in the schema. In this case, it looks like you want a choice element, for example:

<xs:schema xmlns:xs="[schema namespace]">
  <xs:element name="Root">
    <xs:complexType>
      <xs:choice>
        <xs:element name="Hierarchy">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Subjects">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Subject" type="xs:string" maxOccurs="unbounded" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Subjects">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Subject" type="xs:string" maxOccurs="unbounded" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:sequence>
          <xs:element name="Subject" type="xs:string" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

With this schema, someone writing a conforming XML document can now choose whether to use the "Hierarchy" element, the "Subjects" element, or just write a pile of "Subject" elements into the root element.

At this point, the schema is complex enough that you should start separating out complex types from the structure definition, primarily so you don't have to repeat the "Subjects" element definition:

<xs:schema xmlns:xs="[schema namespace]">
  <xs:element name="Root">
    <xs:complexType>
      <xs:choice>
        <xs:element name="Hierarchy">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Subjects" type="SubjectsType" />
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Subjects" type="SubjectsType" />
        <xs:sequence>
          <xs:element name="Subject" type="xs:string" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="SubjectsType">
    <xs:sequence>
      <xs:element name="Subject" type="xs:string" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

For further readability and ease of modification/extension and maintentance, I'd recommend separate type definitions for all three types:

<xs:schema xmlns:xs="[schema namespace]">
  <xs:element name="Root">
    <xs:complexType>
      <xs:choice>
        <xs:element name="Hierarchy" type="HierarchyType" />
        <xs:element name="Subjects" type="SubjectsType" />
        <xs:sequence>
          <xs:element name="Subject" type="SubjectType" maxOccurs="unbounded" />
        </xs:sequence>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="HierarchyType">
    <xs:sequence>
      <xs:element name="Subjects" type="SubjectsType" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="SubjectsType">
    <xs:sequence>
      <xs:element name="Subject" type="SubjectType" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <xs:simpleType name="SubjectType">
    <xs:restriction base="xs:string" />
  </xs:simpleType>
</xs:schema>

Defining "SubjectType" this way is a little overkill, but if you ever need to change what "Subject" elements are, this is the easiest schema to modify.

This article has been dead for over six months. Start a new discussion instead.