JMU
Imposing Structure on XML Documents Using a Schema
An Introduction to Schemas


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu


Motivation
Resolving these Problems
Schemas
The Schema Element
The Schema Element (cont.)

An Example

xmlexamples/timetable/schema/timetable.xsd (Fragment: schema)
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified">
        
Different Approaches to Specifying Schemas
The attribute Element
The element Element
The simpleType Element
The simpleType Element (cont.)

An Example

xmlexamples/timetable/schema/timetable.xsd (Fragment: simpleType)
    <xs:simpleType name="timeoremptytype">
        <xs:union memberTypes="xs:time emptystring"/>
    </xs:simpleType>
        
The complexType Element
The complexType Element (cont.)

An Example

xmlexamples/timetable/schema/timetable.xsd (Fragment: complexType)
    <xs:complexType name="timetabletype">
        <xs:sequence>
            <xs:element name="train" type="traintype" 
                        minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        
        <xs:attribute name="title" type="xs:string"/>
        <xs:attribute name="subtitle" type="xs:string"/>
    </xs:complexType>
        
The restriction Element
The restriction Element (cont.)

An Example

xmlexamples/timetable/schema/timetable.xsd (Fragment: restriction)
    <xs:simpleType name="normaldaysenum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Daily"/>
            <xs:enumeration value="Mo-Fr"/>
            <xs:enumeration value="Sa"/>
            <xs:enumeration value="Su"/>
        </xs:restriction>
    </xs:simpleType>
        
The extension Element
The extension Element (cont.)

An Example

xmlexamples/transcript/schema/transcript.xsd (Fragment: extension)
    <xs:complexType name="gradetype">
        <xs:attribute name="course" type="xs:string" 
            use="required"/>
        <xs:attribute name="passfail"/>
    </xs:complexType>
    
    
    <xs:complexType name="gradetypepf">
        <xs:complexContent>
            <xs:extension base="gradetype">
                <xs:attribute name="letter" type="gradeenumpf" 
                    use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    
    
    <xs:complexType name="gradetypeabcdf">
        <xs:complexContent>
            <xs:extension base="gradetype">
                <xs:attribute name="letter" type="gradeenumabcdf" 
                    use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
        
The simpleContent Element
The simpleContent Element (cont.)

An Example

xmlexamples/timetable/schema/timetable.xsd (Fragment: simpleContent)
    <xs:complexType name="stoptimetype">
        <xs:simpleContent>
            <xs:extension base="timeoremptytype">
                <xs:attribute name="status" type="statusenum"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
        
The complexContent Element
The alternative Element
The alternative Element (cont.)

An Example

xmlexamples/transcript/schema/transcript.xsd (Fragment: alternative)
        <xs:sequence>
            <xs:element name="grade" type="gradetype"  
                        minOccurs="0" maxOccurs="unbounded">
                <xs:alternative test="@passfail eq 'true'" 
                                type="gradetypepf" />
                <xs:alternative                            
                                type="gradetypeabcdf" />
            </xs:element>
        </xs:sequence>
        
The assert Element
The aseert Element (cont.)

An Example

xmlexamples/transcript/schema/transcript.xsd (Fragment: assert)
        <!-- Ensure that at most 1 course is Pass/Fail in any term -->
        <xs:assert test="count(grade[@passfail]) le 1"/>
        
The Complete Timetable Example
xmlexamples/timetable/schema/timetable.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified">
    
    <!-- Types -->    
    <xs:simpleType name="emptystring">
        <xs:restriction base="xs:string">
            <xs:enumeration value=""/>
        </xs:restriction>
    </xs:simpleType>


    <xs:simpleType name="normaldaysenum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Daily"/>
            <xs:enumeration value="Mo-Fr"/>
            <xs:enumeration value="Sa"/>
            <xs:enumeration value="Su"/>
        </xs:restriction>
    </xs:simpleType>
    
    
    <xs:simpleType name="statusenum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Ar"/>
            <xs:enumeration value="Dp"/>
        </xs:restriction>
    </xs:simpleType>


    <xs:complexType name="stoptimetype">
        <xs:simpleContent>
            <xs:extension base="timeoremptytype">
                <xs:attribute name="status" type="statusenum"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>


    <xs:complexType name="stoptype">
        <xs:sequence>
            <xs:element name="station" type="xs:string"/>
            <xs:element name="time" type="stoptimetype" 
                        minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    
    
    <xs:simpleType name="timeoremptytype">
        <xs:union memberTypes="xs:time emptystring"/>
    </xs:simpleType>
    
    
    <xs:complexType name="timetabletype">
        <xs:sequence>
            <xs:element name="train" type="traintype" 
                        minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        
        <xs:attribute name="title" type="xs:string"/>
        <xs:attribute name="subtitle" type="xs:string"/>
    </xs:complexType>
    
    
    <xs:complexType name="traintype">
        <xs:sequence> 
            <xs:element name="stop" type="stoptype" 
                        minOccurs="1" maxOccurs="unbounded"/>
        </xs:sequence>
        
        <xs:attribute name="businessclass" type="yesnoenum"/>
        <xs:attribute name="normaldays" type="normaldaysenum"/>
        <xs:attribute name="number" type="xs:positiveInteger"/>
        <xs:attribute name="reservations" type="yesnoenum"/>
    </xs:complexType>
    
    
    <xs:simpleType name="yesnoenum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="YES"/>
            <xs:enumeration value="NO"/>
        </xs:restriction>
    </xs:simpleType>

    <!-- Elements -->

    <xs:element name="timetable" type="timetabletype" />
    
</xs:schema>
        
The Complete Transcript Example
xmlexamples/transcript/schema/transcript.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
    elementFormDefault="qualified"
    vc:minVersion="1.1"> 

    <!-- Types -->
    <xs:complexType name="transcripttype">
        <xs:sequence>
            <xs:element name="term" type="termtype" 
                        minOccurs="1" maxOccurs="unbounded" />
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="termtype">
        <xs:sequence>
            <xs:element name="grade" type="gradetype"  
                        minOccurs="0" maxOccurs="unbounded">
                <xs:alternative test="@passfail eq 'true'" 
                                type="gradetypepf" />
                <xs:alternative                            
                                type="gradetypeabcdf" />
            </xs:element>
        </xs:sequence>
        
        <xs:attribute name="year" type="xs:integer" />
        <xs:attribute name="semester" type="semesterenum" />
        
        <!-- Ensure that at most 1 course is Pass/Fail in any term -->
        <xs:assert test="count(grade[@passfail]) le 1"/>
    </xs:complexType>

    <xs:complexType name="gradetype">
        <xs:attribute name="course" type="xs:string" 
            use="required"/>
        <xs:attribute name="passfail"/>
    </xs:complexType>
    
    
    <xs:complexType name="gradetypepf">
        <xs:complexContent>
            <xs:extension base="gradetype">
                <xs:attribute name="letter" type="gradeenumpf" 
                    use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    
    
    <xs:complexType name="gradetypeabcdf">
        <xs:complexContent>
            <xs:extension base="gradetype">
                <xs:attribute name="letter" type="gradeenumabcdf" 
                    use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
    

    <xs:simpleType name="gradeenum">
        <xs:restriction base="xs:string" />
    </xs:simpleType>
    
    
    <xs:simpleType name="gradeenumpf">
        <xs:restriction base="gradeenum">
            <xs:enumeration value="P" />
            <xs:enumeration value="F" />
        </xs:restriction>
    </xs:simpleType>
    
    
    <xs:simpleType name="gradeenumabcdf">
        <xs:restriction base="gradeenum">
            <xs:enumeration value="A" />
            <xs:enumeration value="B" />
            <xs:enumeration value="C" />
            <xs:enumeration value="D" />
            <xs:enumeration value="F" />
        </xs:restriction>
    </xs:simpleType>


    <xs:simpleType name="semesterenum">
        <xs:restriction base="xs:string">
            <xs:enumeration value="Fall" />
            <xs:enumeration value="Spring" />
        </xs:restriction>
    </xs:simpleType>
    
    
    <!-- Elements -->
    <xs:element name="transcript" type="transcripttype" />
</xs:schema>