Creating Simple Types

Most of the types that I've used in book.xsd are simple types that come built into the XML schema specification, such as xsd:string, xsd:integer, xsd:date, and so on. However, take a look at the attribute named bookID—this attribute is declared to be of the type catalogID:

<xsd:complexType name="books">
    <xsd:element name="book" minOccurs="0" maxOccurs="10">
        <xsd:complexType>
            <xsd:element name="bookTitle" type="xsd:string"/>
            <xsd:element name="pubDate" type="xsd:date" minOccurs='0'/>
            <xsd:element name="replacementValue" type="xsd:decimal"/>
            <xsd:element name="maxDaysOut">
                <xsd:simpleType base="xsd:integer">
                    <xsd:maxExclusive value="14"/>
                 </xsd:simpleType>
            </xsd:element>
            <xsd:attribute name="bookID" type="catalogID"/>
        </xsd:complexType>
    </xsd:element>
</xsd:complexType>

This type, catalogID, is itself a simple type that is not built into the XML schema specification; instead, I've defined it with the <simpleType> element, like this:

<xsd:complexType name="books">
    <xsd:element name="book" minOccurs="0" maxOccurs="10">
        <xsd:complexType>
            <xsd:element name="bookTitle" type="xsd:string"/>
            <xsd:element name="pubDate" type="xsd:date" minOccurs='0'/>
            <xsd:element name="replacementValue" type="xsd:decimal"/>
            <xsd:element name="maxDaysOut">
                <xsd:simpleType base="xsd:integer">
                    <xsd:maxExclusive value="14"/>
                 </xsd:simpleType>
            </xsd:element>
            <xsd:attribute name="bookID" type="catalogID"/>
        </xsd:complexType>
    </xsd:element>
</xsd:complexType>
<xsd:simpleType name="catalogID" base="xsd:string">
    <xsd:pattern value="d{3}-d{4}-d{3}"/>
</xsd:simpleType>

Note in particular that you must base new simple types such as catalogID on already existing simple type (either a built-in simple type or one that you've created; here, I'm using the built-in xsd:string type). To do that, you use the base attribute in the <xsd:simpleType> element. In the case of the catalogID type, I've based it on the xsd:string type with the attribute/value pair base="xsd:string". To describe the properties of new simple types, XML schemas use facets, which are discussed in the next section.

Creating Simple Types Using Facets

Using facets lets you restrict the data that a simple type can hold. For example, say that you want to create a simple type named dayOfMonth that can hold only values between 1 and 31, inclusive. In that case, you can define it this way, using the two facets minInclusive and maxInclusive:

<xsd:simpleType name="dayOfMonth" base="xsd:integer">
     <xsd:minInclusive value="1"/>
     <xsd:maxInclusive value="31"/>
 </xsd:simpleType>

Now that you've created this new simple type, you can declare elements and attributes of this type.

In book.xsd, the catalogID simple type is even more powerful than this dayOfMonth simple type. The catalogID simple type uses the pattern facet to specify a regular expression (that is, a pattern set up to match text in the format that you specify) that text strings values for this type must satisfy:

<xsd:simpleType name="catalogID" base="xsd:string">
    <xsd:pattern value="d{3}-d{4}-d{3}"/>
</xsd:simpleType>

In this case, the text in the simpleType type must match the regular expression "d{3}-d{4}-d{3}", which stands for three digits, a hyphen, four digits, another hyphen, and three digits.

About Regular Expressions

The regular expressions used in XML schema facets are the same as those used in the Perl programming language. You can find the complete documentation for Perl regular expressions at the Comprehensive Perl Archive Network (CPAN) Web site: http://www.cpan.org/doc/manual/html/pod/perlre.html. (Regular expressions are not a skill that you'll need in this book.)


The catalogID type is the type of the <book> element's bookID attribute, so I can specify book ID values like this in book.xml, matching the regular expression that I've used for this attribute:

<book bookID="123-4567-890">
    <bookTitle>Earthquakes for Breakfast</bookTitle>
    <pubDate>2001-10-20</pubDate>
    <replacementValue>15.95</replacementValue>
    <maxDaysOut>14</maxDaysOut>
</book>

What facets are there, and what built-in simple types support them? You'll find the seven general facets, listed by the simple types that support them, in Table 5.3.

Table 5.3. Simple Types and Applicable Facets
TypeLengthminLengthmaxLengthPatternEnumeration
binaryxxxxx
boolean   x 
byte   xx
century   xx
date   xx
decimal   xx
double   xx
ENTITIESxxx x
ENTITYxxxxx
float   xx
IDxxxxx
IDREFxxxxx
IDREFSxxx x
int   xx
integer   xx
languagexxxxx
long   xx
month   xx
Namexxxxx
NCNamexxxxx
negativeInteger   xx
NMTOKENxxxxx
NMTOKENSxxx x
nonNegativeInteger   xx
nonPositiveInteger   xx
NOTATIONxxxxx
positiveInteger   xx
QNamexxxxx
recurringDate  xx 
recurringDay  xx 
recurringDuration  xx 
short   xx
stringxxxxx
time   xx
timeDuration  xx 
timeInstant  xx 
timePeriod  xx 
unsignedByte   xx
unsignedInt   xx
unsignedLong   xx
unsignedShort   xx
uriReferencexxxxx
year   xx

The numeric simple types, and those simple types that can be ordered, also have some additional facets, which you see in Tables 5.4 and 5.5.

Table 5.4. Ordered Simple Types and Applicable Facets, Part 1
TypemaxInclusivemaxExclusiveminInclusive
binary   
bytexxx
centuryxxx
datexxx
decimalxxx
doublexxx
floatxxx
intxxx
integerxxx
longxxx
monthxxx
negativeIntegerxxx
nonNegativeIntegerxxx
nonPositiveIntegerxxx
positiveIntegerxxx
recurringDatexxx
recurringDayxxx
recurringDurationxxx
shortxxx
stringxxx
timexxx
timeDurationxxx
timeInstantxxx
timePeriodxxx
unsignedBytexxx
unsignedIntxxx
unsignedLongxxx
unsignedShortxxx
yearxxx

Table 5.5. Ordered Simple Types and Applicable Facets, Part 2
TypeminExclusivePrecisionScaleEncoding
binary   x
bytexxx 
centuryx   
datex   
decimalxxx 
doublex   
floatx   
intxxx 
integerxxx 
longxxx 
monthx   
negativeIntegerxxx 
nonNegativeIntegerxxx 
nonPositiveIntegerxxx 
positiveIntegerxxx 
recurringDatex   
recurringDayx   
recurringDurationx   
shortxxx 
stringx   
timex   
timeDurationx   
timeInstantx   
timePeriodx   
unsignedBytexxx 
unsignedIntxxx 
unsignedLongxxx 
unsignedShortxxx 
yearx   

Some additional facets that have to do with dates and times apply to simple types, and you'll find them in Table 5.6.

Table 5.6. Time and Date Simple Types and Applicable Facets
TypePeriodDuration
centuryxx
datexx
monthxx
recurringDatexx
recurringDayxx
recurringDurationxx
timexx
timeDurationxx
timeInstantxx
timePeriodxx
yearxx

Of all the facets that you see in Tables 5.3, 5.4, and 5.5, my favorites are minInclusive, maxInclusive, pattern, and enumeration. We've seen the first three, but not the enumeration facet yet.

The enumeration facet lets you set up an enumeration of values, exactly as you can do in DTDs (as we saw in the previous chapter). Using an enumeration, you can restrict the possible values of a simple type to a list of values that you specify.

For example, to set up a simple type named weekday whose values can be "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", and "Saturday", you'd define that type like this:

<xsd:simpleType name="weekday" base="xsd:string">
    <xsd:enumeration value="Sunday"/>
    <xsd:enumeration value="Monday"/>
    <xsd:enumeration value="Tuesday"/>
    <xsd:enumeration value="Wednesday"/>
    <xsd:enumeration value="Thursday"/>
    <xsd:enumeration value="Friday"/>
    <xsd:enumeration value="Saturday"/>
</xsd:simpleType>

Using Anonymous Type Definitions

So far, all the element declarations that we've used in the book.xsd schema have used the type attribute to indicate the new element's type. But what if you want to use a type only once? Do you have to go to the trouble of declaring it and naming it, all to use it in only one element declaration?

It turns out that there is an easier way. You can use an anonymous type definition to avoid having to define a whole new type that you'll reference only once. Using an anonymous type definition simply means that you enclose the <xsd:simpleType> or <xsd:complexType> element inside the <xsd:element> element declaration. In this case, you don't assign an explicit value to the type attribute in the <xsd:element> element because the anonymous type that you're using doesn't have a name. (In fact, you can tell that an anonymous type definition is being used if the <xsd:complexType> element doesn't include a type attribute.)

Here's an example from book.xsd; in this case, I'll use an anonymous type definition for the <book> element. This element holds <bookTitle>, <pubDate>, <replacementValue>, and <maxDaysOut> elements. It will also have an attribute named bookID, so it looks like a good one to create from a complex type. Instead of declaring a separate complex type, however, I'll just put the <xsd:complexType> element inside the <xsd:element> element that declares <book>:

<xsd:element name="book" minOccurs="0" maxOccurs="10">

    <xsd:complexType>
    .
    .
    .
    </xsd:complexType>

</xsd:element>

Now I'm free to add the elements that I want inside the <book> element—without defining a named, separate complex type at all:

<xsd:element name="book" minOccurs="0" maxOccurs="10">
    <xsd:complexType>
        <xsd:element name="bookTitle" type="xsd:string"/>
        <xsd:element name="pubDate" type="xsd:date" minOccurs='0'/>
        <xsd:element name="replacementValue" type="xsd:decimal"/>
        .
        .
        .
    </xsd:complexType>
</xsd:element>

You can also use simple anonymous types; for example, the <maxDaysOut> element holds the maximum number of days that a book is supposed to be out. To set the maximum number of days that a book can be out to 14, I use a new simple anonymous type so that I can use the maxExclusive facet, like this:

<xsd:element name="book" minOccurs="0" maxOccurs="10">
    <xsd:complexType>
        <xsd:element name="bookTitle" type="xsd:string"/>
        <xsd:element name="pubDate" type="xsd:date" minOccurs='0'/>
        <xsd:element name="replacementValue" type="xsd:decimal"/>
        <xsd:element name="maxDaysOut">
            <xsd:simpleType base="xsd:integer">
                <xsd:maxExclusive value="14"/>
             </xsd:simpleType>
        </xsd:element>

        .
        .
        .
    </xsd:complexType>
</xsd:element>

You can also include attribute declarations in anonymous type definitions, like this:

<xsd:element name="book" minOccurs="0" maxOccurs="10">
    <xsd:complexType>
        <xsd:element name="bookTitle" type="xsd:string"/>
        <xsd:element name="pubDate" type="xsd:date" minOccurs='0'/>
        <xsd:element name="replacementValue" type="xsd:decimal"/>
        <xsd:element name="maxDaysOut">
            <xsd:simpleType base="xsd:integer">
                <xsd:maxExclusive value="14"/>
             </xsd:simpleType>
        </xsd:element>

        <xsd:attribute name="bookID" type="catalogID"/>
    </xsd:complexType>
</xsd:element>

Now I'll take a look at declaring empty elements.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.77.149