Home | | Service Oriented Architecture | Creating XML Schemas

Chapter: XML and Web Services : Essentials of XML : Creating XML Schemas

Creating XML Schemas

One of the first things that comes to mind for most people when authoring an XML schema is the level of complexity that accompanies it. However, the example in Listing 4.3 demonstrates only a small portion of the power and flexibility within the XML Schema Definition Language. Table 4.1 shows a complete list of every element the XML Schema Definition Language supports.

Creating XML Schemas

 

One of the first things that comes to mind for most people when authoring an XML schema is the level of complexity that accompanies it. However, the example in Listing 4.3 demonstrates only a small portion of the power and flexibility within the XML Schema Definition Language. Table 4.1 shows a complete list of every element the XML Schema Definition Language supports.

TABLE 4.1      XML Schema Elements Supported by the W3C Standard





Each of the elements in Table 4.1 has its own series of attributes and elements, including a series of constraints that can be placed on each element.

 

Authoring an XML schema consists of declaring elements and attributes as well as the “properties” of those elements and attributes. We will begin our look at authoring XML schemas by working our way from the least-complex example to the most-complex example. Because attributes may not contain other attributes or elements, we will start there.

 

Declaring Attributes

 Attributes in an XML document are contained by elements. To indicate that a complex element has an attribute, use the <attribute> element of the XML Schema Definition Language. For instance, if you look at the following section from the PurchaseOrder schema, you can see the basics for declaring an attribute:


<xsd:complexType name=”ProductType”> <xsd:attribute name=”Name” type=”xsd:string”/>


<xsd:attribute name=”Id” type=”xsd:positiveInteger”/> <xsd:attribute name=”Price”>


<xsd:simpleType>


<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>


</xsd:restriction>


</xsd:simpleType>


</xsd:attribute>


<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>


From this, you can see that when declaring an attribute, you must specify a type. This type must be one of the simple types defined in Table 4.2.


TABLE 4.2 The Simple XML Data Types



The types in Table 4.2 can each be further categorized as either a “primitive” data type or a “derived” data type. Here’s a list of the primitive data types:


anyURI


base64Binary


Boolean


date


dateTime


decimal


double


duration

float


gDay


gMonth


gMonthDay


gYear


gYearMonth


hexBinary


NOTATION


QName


string


time


The derived data types are “primitive” or other “derived” data types with restrictions placed on them, such as integer, positiveInteger, and byte. Here’s a list of the derived data types:


byte


ENTITIES


ENTITY


ID


IDREF


IDREFS


int


integer


language


long


Name


NCName


negativeInteger


NMTOKEN


NMTOKENS


nonNegativeInteger


nonPositiveInteger


short


token


unsignedByte


unsignedInt


unsignedLong


unsignedShort


 

Note

 

From the simple types specified in Table 4.2, you may notice what appears to be a group of duplicate or unnecessary types, such as nonNegativeInteger and positiveInteger. Aren’t those two types the same? No, they’re not. If you look closely, you’ll see that nonNegativeInteger is an integer whose value is greater than or equal to zero, whereas the positiveInteger type is an integer whose value is greater than zero, which means a positiveInteger type cannot be zero. Keep this in mind when deciding on the base data type for your elements and attributes, because these small details can greatly influence their acceptable value ranges.

 

 

 

Aside from defining the type of an attribute, the <attribute> element within the XML Schema Definition Language contains attributes to assist in defining when an attribute is optional, whether its values are fixed, what its default value is, and so on. Here’s the basic syntax for the <attribute> element:

 

<attribute  name=””  type=””  [use=””]  [fixed=””]  [default=””]  [ref=””]/>

 

The use attribute can contain one of the following possible values:

 

                optional

 

                prohibited

 

                required

 

If the use attribute is set to required, the parent element must have the attribute; other-wise, the document will be considered invalid. A value of optional indicates the attribute may or may not occur in the document and the attribute may contain any value. By assigning a value of prohibited to the use attribute, you can indicate that the attribute may not appear at all within the parent element.

 

Specifying a value for the default attribute indicates that if the attribute does not appear within the specified element of the XML document, it is assumed to have the value. A value within the fixed attribute indicates the attribute has a constant value.

 

The ref attribute for the <attribute> element indicates that the attribute declaration exists somewhere else within the schema. This allows complex attribute declarations to be defined once and referenced when necessary. For instance, let’s say you’ve “inherited” elements and attributes from another schema and would like to simply reuse one of the attribute declarations within the current schema; this would provide the perfect opportu-nity to take advantage of the ref attribute.

 

Just as attributes can be defined based on the simple data types included in the XML Schema Definition Language, they can also be defined based on <simpleType> elements. This can easily be accomplished by declaring an attribute that contains a <simpleType> element, as the following example demonstrates:

 

<xsd:attribute name=”exampleattribute”> <xsd:simpleType base=”string”>

 

<xsd:length value=”2”/> </xsd:simpleType>

 

</xsd:attribute>

 

<xsd:complexType name=”exampleelement”> <xsd:attribute ref=”exampleattribute”/>

 

</xsd:complexType>

 

From this example, you can see that the XML Schema Definition Language gives the schema author a great deal of control over how attributes are validated. One of the won-derful side effects of the XML Schema Definition Language is its similarity to object-oriented programming. Consider each attribute definition and element definition to be a class definition. These class definitions describe complex structures and behaviors among various different classes, so each individual class definition, whether it’s a simple class or complex class, encapsulates everything necessary to perform its job. The same holds true for the declaration of attributes and elements within an XML document. Each item com-pletely describes itself.

Declaring Elements

 

Elements within an XML schema can be declared using the <element> element from the XML Schema Definition Language. If you look at the following example from Listing 4.3, you can see a simple element declaration using the XML Schema Definition Language:

 

<xsd:element  name=’PurchaseOrder’  type=’PurchaseOrderType’/>

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element  name=”Order”  type=”OrderType”

 

minOccurs=”1” maxOccurs=”1”/> </xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

From this example, you can see that an element’s type may be defined elsewhere within the schema. The location at which an element is defined determines certain characteris-tics about its availability within the schema. For instance, an element defined as a child of the <schema> element can be referenced anywhere within the schema document, whereas an element that is defined when it is declared can only have that definition used once. An element’s type can be defined with either a <complexType> element, a

 

<simpleType> element, a <complexContent> element, or a <simpleContent> element. The validation requirements for the document will influence the choice for an element’s type. For instance, going back our object-oriented analogy, let’s say you define a high-level abstract class and then need to refine its definition for certain situations. In that case, you would create a new class based on the existing one and change its definition as needed. The <complexContent> and <simpleContent> elements work much the same way: They provide a way to extend or restrict the existing simple or complex type defini-tion as needed by the specific instance of the element declaration.

 The basic construction of an element declaration using the <element> element within the XML Schema Definition Language is as follows:


From this, you can see that element declarations offer a myriad of possibilities to the author. For instance, the abstract attribute indicates whether the element being declared may show up directly within the XML document. If this attribute is true, the declared element may not show up directly. Instead, this element must be referenced by another element using the substitutionGroup attribute. This substitution works only if the ele-ment utilizing the substitutionGroup attribute occurs directly beneath the <schema> element. In other words, for one element declaration to be substituted for another, the element using the substitutionGroup attribute must be a top-level element. Why would anyone in his right mind declare an element as abstract? The answer is really quite sim-ple. Let’s say you need to have multiple elements that have the same basic values speci-fied for the attributes on the <element> element. A <complexType> element definition does not allow for those attributes. So, rather than define and set those attribute values for each element, you could make an “abstract” element declaration, set the values once, and substitute the abstract element definition as needed.

The type attribute indicates that the element should be based on a complexType, simpleType, complexContent, or simpleContent element definition. By defining an element’s structure using one of these other elements, the author can gain an incredible amount of control over the element’s definition. We will cover these various element definitions in the “Declaring Complex Elements” section and the “Declaring Simple Types” section later in this chapter.

 

The block attribute prevents any element with the specified derivation type from being used in place of the element. The block attribute may contain any of the following values:

 

                #all

 

                extension

 

                restriction

 

                substitution

 

If the value #all is specified within the block attribute, no elements derived from this element declaration may appear in place of this element. A value of extension prevents any element whose definition has been derived by extension from appearing in place on this element. If a value of restriction is assigned, an element derived by restriction from this element declaration is prevented from appearing in place of this element. Finally, a value of substitution indicates that an element derived through substitution cannot be used in place of this element.

 

The default attribute may only be specified for an element based on a simpleType or whose content is text only. This attribute assigns a default value to an element.

 

The minOccurs and maxOccurs attributes specify the minimum and maximum number of times this element may appear within a valid XML document. Although you may explic-itly set these attributes, they are not required. To indicate that an element’s appearance within the parent element is optional, set the minOccurs attribute to 0. To indicate that the element may occur an unlimited number of times within the parent element, set the maxOccurs attribute to the string “unbounded”.

The nillable attribute indicates whether an explicit null value can be assigned to the element. If this particular attribute is omitted, it is assumed to be false. If this attribute has a value of true, the nil attribute for the element will be true. So what exactly does this do for you, this nillable attribute? Well, let’s say you are writing an application that uses a database that supports NULL values for fields and you are representing your data as XML. Now let’s say you request the data from your database and convert it into some XML grammar. How do you tell the difference between those elements that are empty and those elements that are NULL? That’s where the nillable attribute comes into play. By appending an attribute of nil to the element, you can tell whether it is empty or is actually NULL.

The fixed attribute specifies that the element has a constant, predetermined value. This attribute only applies to those elements whose type definitions are based on simpleType or whose content is text only.

 

Declaring Complex Elements

 

Many times within an XML document, an element may contain child elements and/or attributes. To indicate this within the XML Schema Definition Language, you’ll use the <complexType> element. If you examine the following sample section from Listing 4.3, you’ll see the basics used to define a complex element within an XML schema:

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element  name=”Order”  type=”OrderType”

 

minOccurs=”1” maxOccurs=”1”/> </xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

The preceding sample section specifies the definition of PurchaseOrderType. This par-ticular element contains three child elements—ShippingInformation, BillingInformation, and Order—as well as two attributes: Tax and Total. You should also notice the use of the maxOccurs and minOccurs attributes on the element declara-tions. With a value of 1 indicated for both attributes, the element declarations specify that they must occur one time within the PurchaseOrderType element.

 

The basic syntax for the <complexType> element is as follows:

 

<xsd:complexType name=’’ [abstract=’’] [base=’’] [block=’’] [final=’’] [mixed=’’]/>

 

The abstract attribute indicates whether an element may define its content directly from this type definition or it must define its content from a type derived from this type defini-tion. If this attribute is true, an element must define its content from a derived type defi-nition. If this attribute is omitted or its value is false, an element may define its content directly based on this type definition.

 

The base attribute specifies the data type for the element. This attribute may hold any value from the included simple XML data types listed in Table 4.2.

 

The block attribute indicates what types of derivation are prevented for this element defi-nition. This attribute can contain any of the following values:

 

                #all

 

                extension

 

                restriction

 

A value of #all prevents all complex types derived from this type definition from being used in place of this type definition. A value of extension prevents complex type definitions derived through extension from being used in place of this type definition. Assigning a value of restriction prevents a complex type definition derived through restriction from being used in place of this type definition. If this attribute is omitted, any type definition derived from this type definition may be used in place of this type definition.

 

The mixed attribute indicates whether character data is permitted to appear between the child elements of this type definition. If this attribute is false or is omitted, no character may appear. If the type definition contains a simpleContent type element, this value must be false. If the complexContent element appears as a child element, the mixed attribute on the complexContent element can override the value specified in the current type definition.

 

A <complexType> element in the XML Schema Definition Language may contain only one of the following elements:

 

                all

 

                choice

 

                complexContent

 

                group

 

                sequence

 

                simpleContent

 

For a short description of these elements, refer back to Table 4.1.

 

Declaring Simple Types

 

Sometimes, it’s not necessary to declare a complex element type within an XML schema. In these cases, you can use the <simpleType> element of the XML Schema Definition Language. These element type definitions support an element based on the simple XML data types listed in Table 4.2 or any simpleType declaration within the current schema. For example, let’s take the following section from the PurchaseOrder schema in 


 

Listing 4.3:

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

This type definition defines the PaymentMethodType element definition, which is based on the string data type included in the XML Schema Definition Language. You may notice the use of the <enumeration> element. This particular element is referred to as a facet, which we’ll cover in the next section in this chapter.

 

The basic syntax for defining a simpleType element definition is as follows:

 

<xsd:simpleType name=’’> <xsd:restriction base=’’/>

 

</xsd:simpleType>

The base attribute type may contain any simple XML data type listed in Table 4.2 or any simpleType declared within the schema. Specifying the value of this attribute determines the type of data it may contain. A simpleType may only contain a value; not other ele-ments or attributes.

 

You may also notice the inclusion of the <restriction> element. This is probably the most common method in which to declare types, and it helps to set more stringent boundaries on the values an element or attribute based on this type definition may hold. So, to indicate that a type definition’s value may hold only string values, you would declare a type definition like the following:

 

<xsd:simpleType name=’mySimpleType’> <xsd:restriction base=’xsd:string’/>

 

</xsd:simpleType>

 

Two other methods are available to an XML schema author to “refine” a simple type def-inition: <list> and <union>. The <list> element allows an element or attribute based on the type definition to contain a list of values of a specified simple data type. The <union> element allows you to combine two or more simple type definitions to create a collection of values.

 

Refining Simple Types Using Facets

 

To give greater control over the definition of elements and attributes, the W3C added facets to the XML Schema Definition Language. A facet can only be specified for a <simpleType> element, and it helps determine the set of values for a <simpleType> ele-ment. For example, a facet may help determine the length or size that an element based on the <simpleType> element may have, an enumeration of acceptable values, and so on. Here’s a list of the facets included within the XML Schema Definition Language:

 

                enumeration

 

                fractionDigits

 

                length

 

                maxExclusive

 

                maxInclusive

 

                maxLength

 

                minExclusive

 

                minInclusive

 

                minLength

 

                pattern

 

                totalDigits

 

                whiteSpace

 

The <enumeration> facet constrains the data type to the specified values. For each valid value for a data type, another <enumeration> element must be defined. The following sample section from Listing 4.3 demonstrates the use of the <enumeration> facet:

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

This example indicates that the only valid values for an element based on

 

PaymentMethodType are the following:

 

                Check

 

                Cash

 

                Credit Card

 

                Debit Card

 

                Other

 

The <fractionDigits> facet specifies the maximum number of decimal digits in the fractional part. The value for this facet must be a nonNegativeInteger. This may sound a bit confusing, but <fractionDigits> determines the number of decimal places allowed to appear within the value for the data type. For example, look at the following attribute declaration from Listing 4.3:

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

The <length> facet determines the number of units of length for the specified data type. For instance, let’s examine the following sample section from the PurchaseOrder schema in Listing 4.3:

 

<xsd:simpleType name=”StateType”> <xsd:restriction base=”xsd:string”>

<xsd:length value=”2”/> <xsd:enumeration value=”AR”/> <xsd:enumeration value=”LA”/>

<xsd:enumeration value=”MS”/> <xsd:enumeration value=”OK”/> <xsd:enumeration value=”TX”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

The preceding sample section indicates that elements derived from the StateType type definition have a string value of “2” (that is, two spaces in length). Furthermore, the only acceptable values for elements derived from the StateType type definition are TX, LA, MS, OK, and AR, as indicated by the <enumeration> elements.

 

The <maxExclusive> facet specifies the upper bound for the values that can be assigned to the element or attribute. This facet ensures that all values are less than the value speci-fied in this facet. The <maxInclusive> facet specifies the maximum value that can be assigned to the element or attribute.

 

The <maxLength> and <minLength> facets specify the maximum and minimum lengths for values in the type definition. Keep in mind that the values specified in these facets are units of length that depend on the data type of the type definition’s value. Also, remember these facets must have a nonNegativeInteger value assigned to them.

 

The <minExclusive> facet specifies the lower bound for the values that can be assigned to the element or attribute. This facet ensures that all values are greater than the value specified in this facet. The <minInclusive> facet specifies the minimum value that can be assigned to the element or attribute.

 

The <pattern> facet applies a specific pattern that the type definition’s value must match. This facet constrains the type definition’s data type to literals, which must match the pattern specified. Furthermore, the value specified for a <pattern> facet must be a regular expression. So what exactly qualifies as a regular expression? Put simply, a regu-lar expression is composed of one or more “atoms” and optional quantifiers combined together with the pipe character (|). For instance, let’s examine the following sample section from Listing 4.3:

 

<xsd:simpleType name=”ZipType”> <xsd:restriction base=”xsd:string”>

 

<xsd:minLength value=”5”/> <xsd:maxLength value=”10”/>

 

<xsd:pattern value=”[0-9]{5}(-[0-9]{4})?”/> </xsd:restriction>

 

</xsd:simpleType>

 

The preceding type definition is for a zip code. In this particular definition, we declare that a valid zip code may only contain numbers 0 through 9; nothing else is allowed. Furthermore, the value for the type definition may contain five numbers listed together; then, if the additional four digits are included, the whole value is separated by a hyphen (-) between the fifth and sixth digits.

 

The <totalDigits> facet specifies the maximum number of digits for a type definition’s value. This value must be a positiveInteger value.

 

The <whiteSpace> facet specifies how whitespace is treated for the type definition’s value. This particular facet can hold one of three values:

 

                 collapse

 

                 preserve

 

                 replace

 

Specifying collapse indicates that all whitespace consisting of more than a single space will be converted to a single space and that all leading and trailing blanks will be removed. A value of preserve leaves the value as is. Assigning a value of replace causes all tabs, line feeds, and carriage returns to be replaced with a single space.

 

Not all type definitions, however, support every facet. The type definition’s data type determines which facets are available. Table 4.3 shows which data types will support which facets.

 

TABLE 4.3  The Simple XML Data Types and Applicable Facets

 



 

Anonymous Type Declarations

 

Sometimes within an XML schema it may not be necessary to create a separate type def-inition for an element or attribute. In such cases, you may use “anonymous” type decla-rations. Let’s pull another sample section from the PurchaseOrder schema in Listing 4.3 and examine it:

 

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”Address” type=”AddressType” minOccurs=”1” maxOccurs=”1”/>

<xsd:choice minOccurs=”1” maxOccurs=”1”>

<xsd:group ref=”BillingInfoGroup”/>

<xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

This section defines the type definition for InfoType. If you look closely, you’ll see the declaration of a <Name> element that does not have a type attribute specified. Instead, the <element> element, itself, contains a <simpleType> element without a name attribute specified. This is known as an “anonymous” type definition. If you’re only using this type definition once, there is no need to go through the trouble of declaring and naming it. However, anonymous type declarations are not limited to <simpleType> elements; you can also create an anonymous type definition for a <complexType> element. For instance, let’s look at the following example from Listing 4.3:

 

<xsd:complexType name=”OrderType”> <xsd:sequence>

 

<xsd:element  name=”Product”  type=”ProductType”

 

minOccurs=”1” maxOccurs=”unbounded”/> </xsd:sequence>

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute  name=”ItemsSold”  type=”xsd:positiveInteger”/>

 

</xsd:complexType>

 

<xsd:complexType name=”ProductType”> <xsd:attribute name=”Name” type=”xsd:string”/>

 

<xsd:attribute name=”Id” type=”xsd:positiveInteger”/> <xsd:attribute name=”Price”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>

 

This example shows the type definition for elements based on OrderType. This type defi-nition contains an element named Product, which is based on the ProductType type def-inition. Because we only reference the ProductType type definition once, this would be a good candidate for which to use an anonymous type definition. Using an anonymous type definition, the preceding example changes to the following:

 

<xsd:complexType name=”OrderType”> <xsd:sequence>

 

<xsd:element name=”Product” minOccurs=”1” maxOccurs=”unbounded”> <xsd:complexType>

 

<xsd:attribute name=”Name” type=”xsd:string”/>

<xsd:attribute name=”Id” type=”xsd:positiveInteger”/>

<xsd:attribute name=”Price”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>

 

</xsd:element>

 

</xsd:sequence>

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”ItemsSold” type=”xsd:positiveInteger”/> </xsd:complexType>

 

You can see from this example that the only real change necessary was to move the <complexType> element for the ProductType type definition to be contained by the

 

<element> declaration for Product.

 Specifying Mixed Content for Elements

 

So far we have declared a variety of different elements in Listing 4.3. Some of the ele-ments have text only, some contain elements only, and some contain elements and attrib-utes. However, we have not specified, yet, how to mix the content of elements—that is, mix text with child elements. One of the most overlooked attributes of the <complexType> element is the mixed attribute. If this attribute is set to true, elements based on this type definition can mix their contents with both text and child elements. For instance, let’s examine the following sample XML document:

 

<Letter>

 

<Greeting>Dear Mr.<Name>John Smith</Name>.</Greeting> Your order of <Quantity>1</Quantity> <Product>Big Screen TV </Product> has been shipped.

 

</Letter>

Notice the appearance of text among the child elements of <Letter>. The schema for this XML document would appear as follows:

 

<xsd:element name=”Letter”> <xsd:complexType mixed=”true”>

 

<xsd:element name=”Greeting”> <xsd:complexType mixed=”true”>

 

<xsd:element name=”Name” type=”xsd:string”/> </xsd:complexType>

 

</xsd:element>

 

<xsd:element name=”Quantity” type=”xsd:postiveInteger”/> <xsd:element name=”Product” type=”xsd:string”/>

 

</xsd:complexType>

 

</xsd:element>

 

So what’s the point of having mixed content? Well, if you needed to uniquely identify something within a paragraph or sentence, specifying an element as having mixed con-tent might be useful. For one, you could easily format that one unique element differ-ently from its parent element. You could also perform some special processing of that element within an application. However, unless it is absolutely necessary to use mixed content within an element, it is highly recommended that each element contain either text or other elements (not both, because some undesirable side effects may arise). For instance, in the preceding sample XML document, if you check the value of the text property for the <Greeting> element using the XMLDOM provided by Microsoft, it would contain this:

 

Dear  Mr.John  Smith,

 

Annotating Schemas

 

In a perfect world, everyone would be able to look at our XML schemas and automati-cally know what everything is and why it shows up in particular places. Although a good self-describing document can accomplish this to some extent with sensible element and attribute names, the truth of the matter is that most people I’ve met—well, all of them actually—are not mind readers. What may seem obvious to you may not be obvious to others. For that very reason, it helps to document your schemas. Within the XML Schema Definition Language, this can be accomplished using annotations. The XML Schema Definition Language defines three new elements to add annotations to an XML schema:

 

                <annotation>

 

                <appInfo>

 

                <documentation>

 

The <annotation> element contains the <appInfo> and <documentation> elements. In other words, you cannot use the <appInfo> and <documentation> elements by them-selves—they must be contained within an <annotation> element. To see how this works, let’s examine the following sample section from Listing 4.3:

 

<xsd:annotation>

 

<xsd:documentation>

 

Purchase order schema for an online grocery store.

</xsd:documentation>

 

</xsd:annotation>

 

In the preceding example, the <annotation> and <documentation> elements help to identify the purpose of this particular XML schema. In Listing 4.3, the <annotation> element appears as a child element of the <schema> element. However, the <annotation> element can appear as a child of any elements listed in Table 4.2, with the exception of the <documentation> and <appInfo> elements. Really, the only difference between the two elements is the target audience. For the <documentation> element, the information it contains is meant to be read by users, whereas the information contained within an <appInfo> element is meant to be read and utilized by applications.

 

Model Groups

 

A model group, at least in terms of a schema definition, is a logically grouped set of ele-ments. A model group within the XML Schema Definition Language consists of a “com-positor” and a list of “particles” (or element declarations). A model group can be constructed using one of the following XML Schema Definition elements:



<all>


<choice>


<sequence>


You can declare a group of elements that should be logically associated together by using the <group> element from the XML Schema Definition Language. Here’s the basic syn-tax for the <group> element:


<group  name=””  [maxOccurs=””]  [minOccurs=””]  [ref=””]>

 

</group>

 

By default, the maxOccurs and minOccurs attributes are set to 1. The ref attribute is used after you have defined the <group> element and you wish to reference it, as the following example shows:

<xsd:group name=”exampleGroup”> <xsd:all>

 

<xsd:element name=”Element1” type=”xsd:string”/> <xsd:element name=”Element2” type=”xsd:string”/> <xsd:element name=”Element3” type=”xsd:string”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:element name=”ParentElement”> <xsd:complexType>

 

<xsd:group ref=”exampleGroup”/> </xsd:complexType>

 

</xsd:element>

 

All Groups

 

When the order in which child elements appear within their parent element is not impor-tant, you may use an <all> element from the XML Schema Definition Language. The <all> element indicates that the elements declared within it may appear in any order within the parent element. For instance, let’s examine the InfoType type definition from Listing 4.3:

 

<xsd:group name=”ShippingInfoGroup”> <xsd:all>

 

<xsd:element name=”DeliveryDate” type=”DateType”/> <xsd:element name=”Method” type=”DeliveryMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:group name=”BillingInfoGroup”> <xsd:all>

 

<xsd:element name=”BillingDate” type=”DateType”/> <xsd:element name=”PaymentMethod” type=”PaymentMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”Address” type=”AddressType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:choice minOccurs=”1” maxOccurs=”1”> <xsd:group ref=”BillingInfoGroup”/> <xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

<xsd:simpleType name=”DateType”> <xsd:restriction base=”xsd:date”/>

 

</xsd:simpleType>

 

<xsd:simpleType name=”DeliveryMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”USPS”/> <xsd:enumeration value=”UPS”/> <xsd:enumeration value=”FedEx”/> <xsd:enumeration value=”DHL”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

Notice the occurrence of the <all> elements. In this particular case, either the

 

<DeliveryDate> and <Method> elements may appear in any order or the <BillingDate> and <PaymentMethod> elements may appear in any order.

 

Choices

 

Sometimes you might want to declare that any one of a possible group of elements may appear within an element, but not all of them. This is accomplished by using the <choice> element of the XML Schema Definition Language. Let’s examine the follow-ing sample section from Listing 4.3:

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element  name=”Order”  type=”OrderType”  minOccurs=”1”

 

maxOccurs=”1”/> </xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

<xsd:group name=”ShippingInfoGroup”> <xsd:all>

 

<xsd:element name=”DeliveryDate” type=”DateType”/> <xsd:element name=”Method” type=”DeliveryMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:group name=”BillingInfoGroup”> <xsd:all>

 

<xsd:element name=”BillingDate” type=”DateType”/> <xsd:element name=”PaymentMethod” type=”PaymentMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”Address” type=”AddressType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:choice minOccurs=”1” maxOccurs=”1”> <xsd:group ref=”BillingInfoGroup”/> <xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

<xsd:simpleType name=”DateType”> <xsd:restriction base=”xsd:date”/>

 

</xsd:simpleType>

 

<xsd:simpleType name=”DeliveryMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration  value=”USPS”/>

 

<xsd:enumeration value=”UPS”/> <xsd:enumeration value=”FedEx”/> <xsd:enumeration value=”DHL”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

In this case, because the information between the <ShippingInformation> and <BillingInformation> elements is so similar, we only want to define that type defini-tion once. However, because the two date elements—<DeliveryDate> and <BillingDate>—could not appear in both places, we’ve decided to create a choice: either the <DeliveryDate> element can appear within the element or the <BillingDate> element can appear, but not both. Furthermore, you can specify the minimum and maxi-mum number of times the selected item may appear within the parent element by using the minOccurs and maxOccurs attributes of the <choice> element.

Sequences

 

The <sequence> element in the XML Schema Definition Language requires the elements contained within it to appear in the same order in the parent element. For instance, let’s examine the following sample section from Listing 4.3:

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

<xsd:element  name=”Order”  type=”OrderType”  minOccurs=”1”

 

maxOccurs=”1”/> </xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

According to this type definition, the <ShippingInformation>, <BillingInformation>, and <Order> elements may appear within the <PurchaseOrder> element in any order.

 

If we want to indicate that the <ShippingInformation> element must appear first, then the <BillingInformation> element, and then the <Order> element, we could do the following:

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:sequence>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element  name=”Order”  type=”OrderType”  minOccurs=”1”

 

maxOccurs=”1”/> </xsd:sequence> <xsd:attribute name=”Tax”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

Attribute Groups

 

Just as you can logically group a set of elements together using the <group> element within the XML Schema Definition Language, you can create a logical group of attributes to do the same thing. In this case, though, you will need to use the <attributeGroup> element. Here’s the basic syntax for the

 

<attributeGroup>  element:

 

<attributeGroup [name=””] [ref=””]> <attribute …/>

 

<attribute  …/>

 

.

 

.

 

.

 

</attributeGroup>

 

Following the preceding syntax, we could define a group of attributes that can be associ-ated with one another, as the following example shows:

 

<xsd:attributeGroup name=”exampleGroup”> <xsd:attribute name=”Attr1” type=”xsd:string”/>

 

<xsd:attribute name=”Attr2” type=”xsd:positiveInteger”/> <xsd:attribute name=”Attr3” type=”xsd:date”/>

 

</xsd:attributeGroup>

 

<xsd:element name=”exampleElement”> <xsd:complexType>

 

<xsd:attributeGroup ref=”exampleGroup”/> </xsd:complexType>

 

</xsd:element>

 

The preceding example creates a group of attributes named exampleGroup. This group consists of three attributes: Attr1, Attr2, and Attr3. Also, we’ve defined a complex ele-ment named <exampleElement>, which then references the group of attributes. It is the equivalent of the following:

 

<xsd:element name=”exampleElement”> <xsd:complexType>

 

<xsd:attribute name=”Attr1” type=”xsd:string”/> <xsd:attribute name=”Attr2” type=”xsd:positiveInteger”/>

 

<xsd:attribute name=”Attr3” type=”xsd:date”/> </xsd:complexType>

 

</xsd:element>

 

Targeting Namespaces

 

You can view an XML schema as a collection of type definitions and element declara-tions targeted for a specific namespace. Namespaces allow us to distinguish element dec-larations and type definitions of one schema from another. We can assign an intended namespace for an XML schema by using the targetNamespace attribute on the <schema> element. By assigning a target namespace for the schema, we indicate that an XML doc-ument whose elements are declared as belonging to the schema’s namespace should be validated against the XML schema. We will discuss namespaces in Chapter 5, “The X-Files: XPath, XPointer, and XLink.” For instance, we could indicate a target namespace for our PurchaseOrder schema as indicated in Listing 4.4.

 

LISTING 4.4 PurchaseOrder1.xsd Contains the Schema Definition for PurchaseOrder.xml with a Target Namespace

 

<xsd:schema  targetNamespace=”http://www.eps-software.com/poschema”

 

xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns=”http://www.eps-software.com/poschema” elementFormDefault=”unqualified”

 

attributeFormDefault=”unqualified”>

 

<xsd:annotation>

 

<xsd:documentation>

 

Purchase Order schema for an online grocery store. </xsd:documentation>

 

</xsd:annotation>

 

<xsd:element  name=”PurchaseOrder”  type=”PurchaseOrderType”/>

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”Order” type=”OrderType” minOccurs=”1” maxOccurs=”1”/>

 

</xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

<xsd:group name=”ShippingInfoGroup”> <xsd:all>

 

<xsd:element name=”DeliveryDate” type=”DateType”/> <xsd:element name=”Method” type=”DeliveryMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:group name=”BillingInfoGroup”> <xsd:all>

 

<xsd:element name=”BillingDate” type=”DateType”/> <xsd:element name=”PaymentMethod” type=”PaymentMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”Address” type=”AddressType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:choice minOccurs=”1” maxOccurs=”1”> <xsd:group ref=”BillingInfoGroup”/> <xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

<xsd:simpleType name=”DateType”> <xsd:restriction base=”xsd:date”/>

 

</xsd:simpleType>

 

<xsd:simpleType name=”DeliveryMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”USPS”/> <xsd:enumeration value=”UPS”/>

<xsd:enumeration value=”FedEx”/> <xsd:enumeration value=”DHL”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:complexType name=”AddressType”> <xsd:all>

 

<xsd:element name=”Street” minOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”City” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”State” type=”StateType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”Zip” type=”ZipType” minOccurs=”1” maxOccurs=”1”/>

 

</xsd:all>

 

</xsd:complexType>

 

<xsd:simpleType name=”ZipType”> <xsd:restriction base=”xsd:string”>

 

<xsd:minLength value=”5”/> <xsd:maxLength value=”10”/>

 

<xsd:pattern value=”[0-9]{5}(-[0-9]{4})?”/> </xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”StateType”> <xsd:restriction base=”xsd:string”>

 

<xsd:length value=”2”/> <xsd:enumeration value=”AR”/> <xsd:enumeration value=”LA”/> <xsd:enumeration value=”MS”/>

 

<xsd:enumeration value=”OK”/> <xsd:enumeration value=”TX”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:complexType name=”OrderType”> <xsd:sequence>

 

<xsd:element name=”Product” type=”ProductType” minOccurs=”1” maxOccurs=”unbounded”/>

 

</xsd:sequence>

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”ItemsSold” type=”xsd:positiveInteger”/> </xsd:complexType>

 

<xsd:complexType name=”ProductType”> <xsd:attribute name=”Name” type=”xsd:string”/>

 

<xsd:attribute name=”Id” type=”xsd:positiveInteger”/> <xsd:attribute name=”Price”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>

 

</xsd:schema>

 

Now that we’ve modified our schema file to specify a target namespace, how do we associate the schema with the XML document? This can be accomplished using the http://www.w3.org/2001/XMLSchema-instance namespace and specifying the schema file’s location using the <schemaLocation> element defined within the namespace. Typically, this namespace is given the prefix of xsi. We could then change our PurchaseOrder XML document as indicated in Listing 4.5.

 

LISTING 4.5 PurchaseOrder1.xml Contains a Sample Purchase Order Based on the

 

PurchaseOrder1 Schema Definition in PurchaseOrder1.xsd

 

<po:PurchaseOrder  xmlns:po=”http://www.eps-software.com/poschema”

 

xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”PurchaseOrder1.xsd”

Tax=”5.76”  Total=”75.77”>

 

<ShippingInformation>

 

<Method>USPS</Method>

 

<DeliveryDate>08/12/2001</DeliveryDate> <Name>Dillon Larsen</Name>

 

<Address>

 

<Street>123 Jones Rd.</Street> <City>Houston</City> <State>TX</State> <Zip>77381</Zip>

 

</Address>

 

</ShippingInformation>

 

<BillingInformation>

 

<PaymentMethod>Credit Card</PaymentMethod> <BillingDate>08/09/2001</BillingDate> <Name>Madi Larsen</Name>

 

<Address>

 

<Street>123 Jones Rd.</Street> <City>Houston</City> <State>TX</State> <Zip>77381</Zip>

 

</Address>

 

</BillingInformation>

 

<Order  SubTotal=”70.01”  ItemsSold=”17”>

 

<Product  Name=”Baby  Swiss”  Id=”702890”  Price=”2.89”

Quantity=”1”/>

 

<Product  Name=”Hard  Salami”  Id=”302340”  Price=”2.34”

Quantity=”1”/>

 

<Product  Name=”Turkey”  Id=”905800”  Price=”5.80”

Quantity=”1”/>

 

<Product  Name=”Caesar  Salad”  Id=”991687”  Price=”2.38”

Quantity=”2”/>

 

<Product  Name=”Chicken  Strips”  Id=”133382”  Price=”2.50”

Quantity=”1”/>

 

<Product  Name=”Bread”  Id=”298678”  Price=”1.08”

Quantity=”1”/>

 

<Product  Name=”Rolls”  Id=”002399”  Price=”2.24”

Quantity=”1”/>

 

<Product  Name=”Cereal”  Id=”066510”  Price=”2.18”

Quantity=”1”/>

 

<Product  Name=”Jalapenos”  Id=”101005”  Price=”1.97”

Quantity=”1”/>

LISTING 4.5 continued

 

<Product  Name=”Tuna”  Id=”000118”  Price=”0.92”

Quantity=”3”/>

 

<Product  Name=”Mayonnaise”  Id=”126860”  Price=”1.98”

Quantity=”1”/>

 

<Product  Name=”Top  Sirloin”  Id=”290502”  Price=”9.97”

Quantity=”2”/>

 

<Product  Name=”Soup”  Id=”001254”  Price=”1.33”

Quantity=”1”/>

 

<Product  Name=”Granola  Bar”  Id=”026460”  Price=”2.14”

Quantity=”2”/>

 

<Product  Name=”Chocolate  Milk”  Id=”024620”  Price=”1.58”

Quantity=”2”/>

 

<Product  Name=”Spaghetti”  Id=”000265”  Price=”1.98”

Quantity=”1”/>

 

<Product  Name=”Laundry  Detergent”  Id=”148202”  Price=”8.82”

 

Quantity=”1”/> </Order>

 

</po:PurchaseOrder>

 

By assigning a namespace to the <PurchaseOrder> element, we associate that element with the global <PurchaseOrder> element declaration within our XML schema. Notice, however, that the <PurchaseOrder> element is the only qualified element. If you

 

look back at our <schema> element from Listing 4.4, you’ll see two attributes: elementFormDefault and attributeFormDefault. These attributes can possess one of two values:

 

            qualified

 

            unqualified

 

If a value of unqualified is specified or the elementFormDefault and attributeFormDefault attributes are omitted, the elements or attributes that are not globally declared within the schema (those that are not children of the <schema> ele-ment) do not require a prefix within the XML instance document. However, if a value of qualified is specified, all elements and attributes must have a prefix associated with them. For instance, we could make a change to our PurchaseOrder schema and specify that the elementFormDefault and attributeFormDefault attributes have a value of qualified, as shown in Listing 4.6.

 

LISTING 4.6 PurchaseOrder2.xsd Contains the Schema Definition for PurchaseOrder.xml with a Target Namespace and Qualified Elements and Attributes

 

<xsd:schema  targetNamespace=”http://www.eps-software.com/poschema”

 

xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns=http://www.eps-software.com/poschema

elementFormDefault=”qualified”

attributeFormDefault=”qualified”>

 

<xsd:annotation>

 

<xsd:documentation>

 

Purchase Order schema for an online grocery store. </xsd:documentation>

 

</xsd:annotation>

 

<xsd:element  name=”PurchaseOrder”  type=”PurchaseOrderType”/>

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”Order” type=”OrderType” minOccurs=”1” maxOccurs=”1”/>

 

</xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

<xsd:group name=”ShippingInfoGroup”> <xsd:all>

 

<xsd:element name=”DeliveryDate” type=”DateType”/> <xsd:element name=”Method” type=”DeliveryMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:group name=”BillingInfoGroup”> <xsd:all>

 

<xsd:element name=”BillingDate” type=”DateType”/> <xsd:element name=”PaymentMethod” type=”PaymentMethodType”/>

 

</xsd:all>

 

</xsd:group>

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”Address” type=”AddressType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:choice minOccurs=”1” maxOccurs=”1”> <xsd:group ref=”BillingInfoGroup”/> <xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

<xsd:simpleType name=”DateType”> <xsd:restriction base=”xsd:date”/>

 

</xsd:simpleType>

 

<xsd:simpleType name=”DeliveryMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”USPS”/> <xsd:enumeration value=”UPS”/> <xsd:enumeration value=”FedEx”/> <xsd:enumeration value=”DHL”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:complexType name=”AddressType”> <xsd:all>

 

<xsd:element name=”Street” minOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”City” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”State” type=”StateType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”Zip” type=”ZipType” minOccurs=”1” maxOccurs=”1”/>

 

</xsd:all>

 

</xsd:complexType>

 

<xsd:simpleType name=”ZipType”> <xsd:restriction base=”xsd:string”>

 

<xsd:minLength value=”5”/> <xsd:maxLength value=”10”/>

 

<xsd:pattern value=”[0-9]{5}(-[0-9]{4})?”/> </xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”StateType”> <xsd:restriction base=”xsd:string”>

 

<xsd:length value=”2”/> <xsd:enumeration value=”AR”/> <xsd:enumeration value=”LA”/> <xsd:enumeration value=”MS”/> <xsd:enumeration value=”OK”/> <xsd:enumeration value=”TX”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:complexType name=”OrderType”> <xsd:sequence>

 

<xsd:element name=”Product” type=”ProductType” minOccurs=”1” maxOccurs=”unbounded”/>

 

</xsd:sequence>

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”ItemsSold” type=”xsd:positiveInteger”/> </xsd:complexType>

 

<xsd:complexType name=”ProductType”> <xsd:attribute name=”Name” type=”xsd:string”/>

 

<xsd:attribute name=”Id” type=”xsd:positiveInteger”/> <xsd:attribute name=”Price”>

 

<xsd:simpleType>

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>

 

</xsd:schema>

 

Based on the PurchaseOrder schema in Listing 4.6, the new version of the PurchaseOrder XML would appear as shown in Listing 4.7.

 

LISTING 4.7 PurchaseOrder2.xml Contains a Sample Purchase Order Based on the

 

PurchaseOrder2 Schema Definition in PurchaseOrder2.xsd

 

<po:PurchaseOrder xmlns:po=”http://www.eps-software.com/poschema” xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”purchaseorder2.xsd”

 

Tax=”5.76”  Total=”75.77”>

 

<po:ShippingInformation>

 

<po:Method>USPS</po:Method>

 

<po:DeliveryDate>08/12/2001</po:DeliveryDate> <po:Name>Dillon Larsen</po:Name>

 

<po:Address>

 

<po:Street>123 Jones Rd.</po:Street> <po:City>Houston</po:City> <po:State>TX</po:State> <po:Zip>77381</po:Zip>

 

</po:Address>

 

</po:ShippingInformation>

 

<po:BillingInformation>

 

<po:PaymentMethod>Credit Card</po:PaymentMethod> <po:BillingDate>08/09/2001</po:BillingDate> <po:Name>Madi Larsen</po:Name>

 

<po:Address>

 

<po:Street>123 Jones Rd.</po:Street> <po:City>Houston</po:City> <po:State>TX</po:State> <po:Zip>77381</po:Zip>

 

</po:Address>

 

</po:BillingInformation>

 

<po:Order  SubTotal=”70.01”  ItemsSold=”17”>

 

<po:Product  Name=”Baby  Swiss”  Id=”702890”  Price=”2.89”  Quantity=”1”/>

<po:Product Name=”Hard Salami” Id=”302340” Price=”2.34” Quantity=”1”/> <po:Product Name=”Turkey” Id=”905800” Price=”5.80” Quantity=”1”/> <po:Product Name=”Caesar Salad” Id=”991687” Price=”2.38” Quantity=”2”/> <po:Product Name=”Chicken Strips” Id=”133382” Price=”2.50” Quantity=”1”/> <po:Product Name=”Bread” Id=”298678” Price=”1.08” Quantity=”1”/> <po:Product Name=”Rolls” Id=”002399” Price=”2.24” Quantity=”1”/> <po:Product Name=”Cereal” Id=”066510” Price=”2.18” Quantity=”1”/> <po:Product Name=”Jalapenos” Id=”101005” Price=”1.97” Quantity=”1”/> <po:Product Name=”Tuna” Id=”000118” Price=”0.92” Quantity=”3”/> <po:Product Name=”Mayonnaise” Id=”126860” Price=”1.98” Quantity=”1”/> <po:Product Name=”Top Sirloin” Id=”290502” Price=”9.97” Quantity=”2”/> <po:Product Name=”Soup” Id=”001254” Price=”1.33” Quantity=”1”/> <po:Product Name=”Granola Bar” Id=”026460” Price=”2.14” Quantity=”2”/> <po:Product Name=”Chocolate Milk” Id=”024620” Price=”1.58” Quantity=”2”/> <po:Product Name=”Spaghetti” Id=”000265” Price=”1.98” Quantity=”1”/> <po:Product Name=”Laundry Detergent” Id=”148202” Price=”8.82”

 

 

Quantity=”1”/> </po:Order>

 

</po:PurchaseOrder>

 

 

”Inheriting” from Other Schemas

 

As you can see from the XML schema in Listing 4.6, things can get rather complex and long. Plus, you may wish, at times, to define a common piece for multiple XML schemas and maintain and extend it separately from the individual schemas that need it. For this reason, the W3C included the <include> and <import> elements in the XML Schema Definition Language. Through the use of these elements, you can effectively “inherit” elements and attributes from the referenced schema. For instance, if you look at Listing 4.3, you can see the declaration of an <Address> element. We may want to use this same element over and over again in multiple schemas. However, we wouldn’t want to redefine this element in each schema. Instead, it would be nice to have that element declaration and type definition within a separate document.

As long as the targetNamespace attribute on the <schema> element of both schemas match, or the targetNamespace attribute for the <schema> element in the referenced XML schema is empty, you can “inherit” any and all elements and attributes within the XML schema using the <include> element. The <import> element doesn’t care what the target namespace is in the referenced schema.

 

Going back Listing 4.3, we can separate out the <Address> element declaration (and the various type definitions that go along with it) into its own schema, as shown in Listing 4.8.

 LISTING 4.8 Address.xsd Contains a Sample Address Schema Definition

 

<xsd:schema  xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>

 

<xsd:annotation>

 

<xsd:documentation>

 

Address schema for a typical US address </xsd:documentation>

 

</xsd:annotation>

 

<xsd:element  name=”Address”  type=”AddressType”/>

 

<xsd:complexType name=”AddressType”> <xsd:all>

 

<xsd:element name=”Street” minOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”City” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”State” type=”StateType” minOccurs=”1” maxOccurs=”1”/> <xsd:element name=”Zip” type=”ZipType” minOccurs=”1” maxOccurs=”1”/>

 

</xsd:all>

 

</xsd:complexType>

 

<xsd:simpleType name=”ZipType”> <xsd:restriction base=”xsd:string”>

 

<xsd:minLength value=”5”/> <xsd:maxLength value=”10”/>

 

<xsd:pattern value=”[0-9]{5}(-[0-9]{4})?”/> </xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”StateType”> <xsd:restriction base=”xsd:string”>

 

<xsd:length value=”2”/> <xsd:enumeration value=”AR”/> <xsd:enumeration value=”LA”/>

<xsd:enumeration value=”MS”/> <xsd:enumeration value=”OK”/> <xsd:enumeration value=”TX”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:schema>

 

 

Notice in the new Address schema that we did not specify a value for the targetNamespace attribute. This will allow us to include the schema in a modified version of the PurchaseOrder schema by using the <include> element as shown in Listing 4.9.

 

LISTING 4.9 PurchaseOrder3.xsd Includes the Contents of Address.xsd

 

<xsd:schema  xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>

 

<xsd:include  schemaLocation=”Address.xsd”/>

 

<xsd:annotation>

 

<xsd:documentation>

 

Purchase Order schema for an online grocery store. </xsd:documentation>

 

</xsd:annotation>

 

<xsd:element  name=”PurchaseOrder”  type=”PurchaseOrderType”/>

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”BillingInformation” type=”InfoType” minOccurs=”1” maxOccurs=”1”/>

 

<xsd:element name=”Order” type=”OrderType” minOccurs=”1” maxOccurs=”1”/> </xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Total”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

<xsd:group name=”ShippingInfoGroup”> <xsd:all>

 

<xsd:element name=”DeliveryDate” type=”DateType”/> <xsd:element name=”Method” type=”DeliveryMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:group name=”BillingInfoGroup”> <xsd:all>

 

<xsd:element name=”BillingDate” type=”DateType”/> <xsd:element name=”PaymentMethod” type=”PaymentMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element ref=”Address” minOccurs=”1” maxOccurs=”1”/> <xsd:choice>

 

<xsd:group ref=”BillingInfoGroup”/> <xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

<xsd:simpleType name=”DateType”> <xsd:restriction base=”xsd:date”/>

 

</xsd:simpleType>

 

<xsd:simpleType name=”DeliveryMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”USPS”/> <xsd:enumeration value=”UPS”/> <xsd:enumeration value=”FedEx”/> <xsd:enumeration value=”DHL”/> <xsd:enumeration value=”Other”/>

 

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:complexType name=”OrderType”> <xsd:sequence>

 

<xsd:element name=”Product” type=”ProductType” minOccurs=”1” maxOccurs=”unbounded”/>

 

</xsd:sequence>

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”ItemsSold” type=”xsd:positiveInteger”/> </xsd:complexType>

 

<xsd:complexType name=”ProductType”> <xsd:attribute name=”Name” type=”xsd:string”/>

 

<xsd:attribute name=”Id” type=”xsd:positiveInteger”/> <xsd:attribute name=”Price”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>

 

</xsd:schema>

 

Because we did not explicitly declare a target namespace for the Address schema, we can include it within the new PurchaseOrder schema. Because there is no reference to a namespace, however, we can simply refer to the declared <Address> element in the Address schema without having to qualify it. However, to prevent schemas from getting confused with other <Address> elements from other schemas, we may want to specify a value for the targetNamespace attribute for our Address schema as shown in Listing 4.10.

 

 

LISTING 4.10    Address1.xsd Modified to Specify a Target Namespace

 

<xsd:schema  targetNamespace=http://www.eps-software.com/addressschema

xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

xmlns=”http://www.eps-software.com/addressschema”>

 

<xsd:annotation>

 

<xsd:documentation>

 

Address schema for a typical US address </xsd:documentation>

 

</xsd:annotation>

 

<xsd:element  name=”Address”  type=”AddressType”/>

 

<xsd:complexType name=”AddressType”> <xsd:all>

 

<xsd:element name=”Street” minOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”City” minOccurs=”1” maxOccurs=”1”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element name=”State” type=”StateType” minOccurs=”1” maxOccurs=”1”/> <xsd:element name=”Zip” type=”ZipType” minOccurs=”1” maxOccurs=”1”/>

 

</xsd:all>

 

</xsd:complexType>

 

<xsd:simpleType name=”ZipType”> <xsd:restriction base=”xsd:string”>

 

<xsd:minLength value=”5”/> <xsd:maxLength value=”10”/>

 

<xsd:pattern value=”[0-9]{5}(-[0-9]{4})?”/> </xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”StateType”> <xsd:restriction base=”xsd:string”>

 

<xsd:length value=”2”/> <xsd:enumeration value=”AR”/> <xsd:enumeration value=”LA”/> <xsd:enumeration value=”MS”/>

 

<xsd:enumeration value=”OK”/> <xsd:enumeration value=”TX”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:schema>

Because we have just specified a target namespace for the Address schema, unless the target namespace for the PurchaseOrder schema is the same, we can no longer use the <include> element to “inherit” the element declarations from the Address schema.

 

However, we can use the <import> element to include the newly modified Address schema as shown in Listing 4.11.

 

LISTING 4.11    PurchaseOrder4.xsd “Imports” the Contents of Address1.xsd

 

<xsd:schema xmlns:adr=”http://www.eps-software.com/addressschema” xmlns:xsd=”http://www.w3.org/2001/XMLSchema”>

 

<xsd:import namespace=http://www.eps-software.com/addressschema schemaLocation=”Address1.xsd”/>

 

<xsd:annotation>

 

<xsd:documentation>

 

Purchase Order schema for an online grocery store. </xsd:documentation>

 

</xsd:annotation>

 

<xsd:element  name=”PurchaseOrder”  type=”PurchaseOrderType”/>

 

<xsd:complexType name=”PurchaseOrderType”> <xsd:all>

 

<xsd:element name=”ShippingInformation” type=”InfoType”/> <xsd:element name=”BillingInformation” type=”InfoType”/> <xsd:element name=”Order” type=”OrderType”/>

 

</xsd:all>

 

<xsd:attribute name=”Tax”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute> <xsd:attribute name=”Total”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

</xsd:simpleType>

 

</xsd:attribute>

 

</xsd:complexType>

 

<xsd:group name=”ShippingInfoGroup”> <xsd:all>

 

<xsd:element name=”DeliveryDate” type=”DateType”/> <xsd:element name=”Method” type=”DeliveryMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:group name=”BillingInfoGroup”> <xsd:all>

 

<xsd:element name=”BillingDate” type=”DateType”/> <xsd:element name=”PaymentMethod” type=”PaymentMethodType”/>

 

</xsd:all>

 

</xsd:group>

 

<xsd:complexType name=”InfoType”> <xsd:sequence>

 

<xsd:element name=”Name”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:string”/> </xsd:simpleType>

 

</xsd:element>

 

<xsd:element ref=”adr:Address”/> <xsd:choice>

 

<xsd:group ref=”BillingInfoGroup”/> <xsd:group ref=”ShippingInfoGroup”/>

 

</xsd:choice>

 

</xsd:sequence>

 

</xsd:complexType>

 

<xsd:simpleType name=”DateType”> <xsd:restriction base=”xsd:date”/>

 

</xsd:simpleType>

 

<xsd:simpleType name=”DeliveryMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”USPS”/> <xsd:enumeration value=”UPS”/> <xsd:enumeration value=”FedEx”/> <xsd:enumeration value=”DHL”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:simpleType name=”PaymentMethodType”> <xsd:restriction base=”xsd:string”>

 

<xsd:enumeration value=”Check”/> <xsd:enumeration value=”Cash”/> <xsd:enumeration value=”Credit Card”/> <xsd:enumeration value=”Debit Card”/> <xsd:enumeration value=”Other”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

<xsd:complexType name=”OrderType”> <xsd:sequence>

 

<xsd:element name=”Product” type=”ProductType” maxOccurs=”unbounded”/>

 

</xsd:sequence>

 

<xsd:attribute name=”SubTotal”> <xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”ItemsSold” type=”xsd:positiveInteger”/> </xsd:complexType>

 

<xsd:complexType name=”ProductType”> <xsd:attribute name=”Name” type=”xsd:string”/>

 

<xsd:attribute name=”Id” type=”xsd:positiveInteger”/> <xsd:attribute name=”Price”>

 

<xsd:simpleType>

 

<xsd:restriction base=”xsd:decimal”> <xsd:fractionDigits value=”2”/>

 

</xsd:restriction>

 

</xsd:simpleType>

 

</xsd:attribute>

 

<xsd:attribute name=”Quantity” type=”xsd:positiveInteger”/> </xsd:complexType>

 

</xsd:schema>

 

You can see that the <import> element supports two attributes: namespace and schemaLocation. You’ll also notice the declaration of the adr namespace within the <schema> element. This namespace declaration is necessary for the <import> element to work correctly. The namespace attribute on the <import> element refers to a namespace that has been previously declared within the <schema> element.

 

Summary

 

An XML schema consists of components, primarily elements, attributes, and type defini-tions. These components are assembled within an XML schema to indicate whether an XML document conforms to the schema specified. In May 2001, the W3C finalized its recommendation for the XML Schema Definition Language, which provides the individ-ual language elements needed to create an XML schema.

 

The XML Schema Definition Language provides a very powerful and flexible way in which to validate XML documents. It includes everything from declaring elements and attributes to “inheriting” elements from other schemas, from defining complex element definitions to defining restrictions for even the simplest of data types. This gives the XML schema author such control over specifying a valid construction for an XML docu-ment that there is almost nothing that cannot be defined with an XML schema.

 

DTDs and XML schemas are two very different means to the same end: providing a “roadmap” with which to validate XML documents. However, so much more detail can be specified with an XML schema than with a DTD. Schemas support varying data types and namespaces, and they allow the author to define the structure of an XML document using XML syntax. DTDs are limited to character data types, provide no support for namespaces, and define the structure of an XML document using a very archaic and cumbersome standard. Because an XML schema is nothing more than an XML docu-ment in itself, it can be loaded into an XML parser just like any other XML document that allows applications to provide added functionality with a very common interface through the XMLDOM.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail
XML and Web Services : Essentials of XML : Creating XML Schemas : Creating XML Schemas |


Privacy Policy, Terms and Conditions, DMCA Policy and Compliant

Copyright © 2018-2024 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.