A Complete XML Schema Example

You've covered an awful lot of territory in this tutorial and hopefully have a pretty good understanding of the XSD language and how it is used to create XSD schemas. To help pull together everything that you've learned, it might be helpful for you to see a complete example. If you recall, in Defining Data With DTD Schemas you constructed a DTD for a sports training markup language known as ETML. Listing 7.1 contains the XSD equivalent for this markup language, which puts to use many of the XSD construction techniques you've learned about throughout this tutorial.

Listing 7.1. The etml.xsd XSD Schema Used to Validate ETML Documents
 1: <?xml version="1.0"?>
 3: <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 4:   <xsd:element name="trainlog">
 5:     <xsd:complexType>
 6:       <xsd:sequence>
 7:         <xsd:element name="session" type="sessionType" minOccurs="0"
 8:           maxOccurs="unbounded"/>
 9:       </xsd:sequence>
10:     </xsd:complexType>
11:   </xsd:element>
13:   <xsd:complexType name="sessionType">
14:     <xsd:sequence>
15:       <xsd:element name="duration" type="xsd:duration"/>
16:       <xsd:element name="distance" type="distanceType"/>
17:       <xsd:element name="location" type="xsd:string"/>
18:       <xsd:element name="comments" type="xsd:string"/>
19:     </xsd:sequence>
21:     <xsd:attribute name="date" type="xsd:date" use="required"/>
22:     <xsd:attribute name="type" type="typeType" use="required"/>
23:     <xsd:attribute name="heartrate" type="xsd:positiveInteger"/>
24:   </xsd:complexType>
26:   <xsd:complexType name="distanceType">
27:     <xsd:simpleContent>
28:       <xsd:extension base="xsd:decimal">
29:         <xsd:attribute name="units" type="unitsType" use="required"/>
30:       </xsd:extension>
31:     </xsd:simpleContent>
32:   </xsd:complexType>
34:   <xsd:simpleType name="typeType">
35:     <xsd:restriction base="xsd:string">
36:       <xsd:enumeration value="running"/>
37:       <xsd:enumeration value="swimming"/>
38:       <xsd:enumeration value="cycling"/>
39:     </xsd:restriction>
40:   </xsd:simpleType>
42:   <xsd:simpleType name="unitsType">
43:     <xsd:restriction base="xsd:string">
44:       <xsd:enumeration value="miles"/>
45:       <xsd:enumeration value="kilometers"/>
46:       <xsd:enumeration value="laps"/>
47:     </xsd:restriction>
48:   </xsd:simpleType>
50: </xsd:schema>

Admittedly, this is considerably more code than the ETML DTD that you saw in Defining Data With DTD Schemas. However, you have to consider the fact that XSDs provide a more exacting approach to data modeling by incorporating rich data types. A quick study of the XSD code for ETML reveals that this schema does a much better job of modeling ETML data than its DTD counterpart. This is primarily due to the data typing features of XSD. Additionally, because XSD is an XML-based language, the code should be a little more familiar to you than the more cryptic code used in DTDs.

The trainlog element is described first in the XSD as containing a sequence of session elements (lines 411). The sessionType data type is created to represent session elements (line 13) and contains child elements that store the duration, distance, location, and comments for a training session (lines 1518). The sessionType data type also includes several attributes that store the date, type, and heart rate for the training session (lines 2123). The remaining distanceType (line 26), typeType (line 34), and unitsType (line 42) data types model the remaining content in ETML documents.

Of course, no schema would be complete without an example XML document that puts it through its paces. Listing 7.2 contains the training log document, modified slightly to accommodate the needs of the XSD schema.

Listing 7.2. The Training Log Example ETML Document
 1: <?xml version="1.0"?>
 3: <trainlog
 4:   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5:   xsi:noNamespaceSchemaLocation="etml.xsd">
 6:   <session date="2005-11-19" type="running" heartrate="158">
 7:     <duration>PT45M</duration>
 8:     <distance units="miles">5.5</distance>
 9:     <location>Warner Park</location>
10:     <comments>Mid-morning run, a little winded throughout.</comments>
11:   </session>
13:   <session date="2005-11-21" type="cycling" heartrate="153">
14:     <duration>PT2H30M</duration>
15:     <distance units="miles">37.0</distance>
16:     <location>Natchez Trace Parkway</location>
17:     <comments>Hilly ride, felt strong as an ox.</comments>
18:   </session>
20:   <session date="2005-11-24" type="running" heartrate="156">
21:     <duration>PT1H30M</duration>
22:     <distance units="miles">8.5</distance>
23:     <location>Warner Park</location>
24:     <comments>Afternoon run, felt reasonably strong.</comments>
25:   </session>
26: </trainlog>

Other than including the standard noNamespaceSchemaLocation attribute to identify the XSD schema document (line 5), the changes to the training log document have to do with the stricter data typing features of XSDs. For example, the date attributes and duration elements conform to the xsd:date and xsd:duration simple types (lines 6, 7, 14, 15, 21, and 22). Beyond those changes, the document is the same as the one you saw in Defining Data With DTD Schemas with the DTD version of the ETML schema. This version of the document, however, is considered valid with respect to the ETML XSD, whereas the previous version is considered valid with respect to the ETML DTD.