Manisha Singh Sanoo
Manisha Singh Sanoo

Reputation: 929

Why is my xsd:choice between elements of different types failing?

I'm trying to validate an XML with XSD, but I can't understand what is wrong with my XSD.

XML

<?xml version="1.0" encoding="UTF-8"?>
<Grades xs:noNamespaceSchemaLocation="grade.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
    <Grade description="Pass">
        <LetterGrade>A+</LetterGrade>
        <GradePoint>4.00</GradePoint>
        <Percentage>80% and above</Percentage>
    </Grade>
    <Grade description="Pass">
        <LetterGrade>A</LetterGrade>
        <GradePoint>4.00</GradePoint>
        <Percentage>70% to 80%</Percentage>
    </Grade>
    <Grade description="Pass">
        <LetterGrade>B</LetterGrade>
        <GradePoint>3.00</GradePoint>
        <Percentage>60% to 70%</Percentage>
    </Grade>
    <Grade description="Pass">
        <LetterGrade>C</LetterGrade>
        <GradePoint>2.00</GradePoint>
        <Percentage>50% to 60%</Percentage>
    </Grade>
    <Grade description="Pass">
        <LetterGrade>D</LetterGrade>
        <GradePoint>1.00</GradePoint>
        <Percentage>40% to 50%</Percentage>
    </Grade>
    <Grade description="Fail">
        <LetterGrade>F</LetterGrade>
        <GradePoint>0</GradePoint>
        <Percentage>Below 40%</Percentage>
    </Grade>
    <Grade description="Incomplete"> Incomplete module/project/independent study due
    to medical/financial/other reasons (may be in 1 or both components of the module).
        <LetterGrade>N</LetterGrade>
    </Grade>
</Grades>

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:complexType name="gradeDetails">
    <xs:sequence>
        <xs:element name="LetterGrade" type="xs:string"/>
        <xs:element name="GradePoint" type="xs:decimal"/>
        <xs:element name="Percentage" type="xs:string"/>
    </xs:sequence>
    <xs:attribute name="description" type="xs:string"/>
</xs:complexType>

<xs:complexType name="gradeNode">
    <xs:sequence>
        <xs:element name="LetterGrade" type="xs:string"/>
    </xs:sequence>
    <xs:attribute name="description" type="xs:string"/>
</xs:complexType>

<xs:element name="Grades">
    <xs:complexType mixed="true">
        <xs:choice>
            <xs:element name="Grade" type="gradeDetails" minOccurs="1" maxOccurs="unbounded"/>
            <xs:element name="Grade" type="gradeNode" minOccurs="1" maxOccurs="unbounded"/>
        </xs:choice>
    </xs:complexType>
</xs:element>

</xs:schema>

I tried validating it with the online validator xmlvalidation.com and I'm getting these errors:

Errors in the XML document:
36: 10 cvc-complex-type.2.3: Element 'Grade' cannot have character [children], because the type's content type is element-only.
36: 10 cvc-complex-type.2.4.b: The content of element 'Grade' is not complete. One of '{"":GradePoint}' is expected.

Somewhat, I understood these error messages. I know it's because there are elements missing in the last <Grade> tag. And to solve it I created 2 global types and used choice. What is wrong with it now?

Upvotes: 1

Views: 799

Answers (1)

kjhughes
kjhughes

Reputation: 111491

Your XSD as written isn't valid on its own because the Grade elements (as children of Grades) cannot have two different types as you're trying to do. You should have received an error message about this along the lines of the following:

cos-element-consistent: Error for type '#AnonType_Grades'. Multiple elements with name 'Grade', with different types, appear in the model group.

and

cos-nonambig: Grade and Grade (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.

The simplified XSD shown below eliminates those errors and successfully validates against your unchanged XML:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="GradeType" mixed="true">
    <xs:sequence>
      <xs:element name="LetterGrade" type="xs:string"/>
      <xs:element name="GradePoint" minOccurs="0" type="xs:decimal"/>
      <xs:element name="Percentage" minOccurs="0" type="xs:string"/>
    </xs:sequence>
    <xs:attribute name="description" type="xs:string"/>
  </xs:complexType>

  <xs:element name="Grades">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element name="Grade" type="GradeType" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Upvotes: 1

Related Questions