Declaring an Element with a Complex Type A complex type can allow an element to contain one or more child elements or attributes, in addition to character data.. You define a complex typ
Trang 1You could limit the permissible content to a set of specific strings by deriving the
element’s type from xsd:string using xsd:enumeration facets, as shown here:
<xsd:element name=”BINDING”>
<xsd:simpleType>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”hardcover”/>
<xsd:enumeration value=”mass market paperback”/>
<xsd:enumeration value=”trade paperback”/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
A BINDING element containing anything other than one of the three strings
specified by the value attributes of the xsd:enumeration elements would
be invalid
As a final example, you can require that an element’s content (or an attribute’s
value) match a particular pattern of characters by restricting the xsd:string type using the xsd:pattern facet, as shown in this declaration:
<xsd:element name=”ISBN”>
<xsd:simpleType>
<xsd:restriction base=”xsd:string”>
<xsd:pattern value=”\d{1}-\d{4}-\d{4}-\d{1}”/>
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
You assign the value attribute of the xsd:pattern facet a description of the re-quired pattern, which is known as a regular expression The regular expression
in the preceding example requires the content to consist of one digit followed by
a hyphen, four digits, another hyphen, four digits, another hyphen, and a single digit Hence, the following would be a valid ISBN element:
<ISBN>0-7356-1020-7</ISBN>
For a description of the regular expressions you can use with the xsd:pattern
ele-ment, see Appendix D “Regular Expressions” in the “XML Schema Part 0:
Primer” page at http://www.w3.org/TR/xmlschema-0/.
The specific facets you can use depend on the particular type you are restricting For a complete list of all the different facets you can use to restrict each of the
Trang 2Chapter 7 Creating Valid XML Documents Using XML Schemas 175
built-in simple types, see the appendix “B Simple Types & their Facets” in the
“XML Schema Part 0: Primer” page at http://www.w3.org/TR/xmlschema-0/.
tip
As an alternative to using an xsd:restriction element inside xsd:simpleType to derive a new simple type, you can use the xsd:list or xsd:union element The xsd:list element creates a new simple type that allows the element (or attribute)
to contain a sequence of values of the base type, which are separated with white
space characters (spaces, tabs, or line breaks) The xsd:union element creates
a new simple type that allows the element (or attribute) to contain a value that conforms to any one of a group of specified base types For details, see the sections “2.3.1 List Types” and “2.3.2 Union Types” in the “XML Schema Part
0: Primer” page at http://www.w3.org/TR/xmlschema-0/.
note
Keep in mind that an xsd:element element with a defined type can use the minOccurs and maxOccurs attributes described in the previous section, as well
as any of the other available xsd:element attributes.
Declaring an Element with a Complex Type
A complex type can allow an element to contain one or more child elements or attributes, in addition to character data
The only built-in complex type you can use for declaring an element is
xsd:anyType This is the default element type that is assigned if you omit the type attribute specification from the xsd:element start-tag and don’t include an
anonymous type definition Here’s an example of an element explicitly declared with this type:
<xsd:element name=”NOTE” type=”xsd:anyType”/>
An element with the xsd:anyType type can include any type of character data It
can also include any element or attribute that is declared directly within the
schema’s xsd:schema element.
Trang 3As explained earlier in the chapter, declaring an element as a direct child of
xsd:schema allows that element to appear as the document element of a
con-forming XML document You can actually include several element declarations,
as well as attribute declarations or named type definitions, as direct children of
xsd:schema Such declarations or type definitions are classified as global A global element declaration cannot include the minOccurs or maxOccurs at-tribute, nor can a global attribute declaration include the use attribute (discussed
later in the chapter) Note that declaring several global elements introduces some ambiguity into the schema, because any of these elements can appear
as the document element of a conforming XML document
For most elements with a complex type, you’ll want to explicitly define the type
so you can specify the elements, attributes, or type of character data that the ele-ment can contain
You define a complex type using the xsd:complexType schema element, which is analogous to the xsd:simpleType element for defining a simple type In the fol-lowing three sections, you’ll learn how to use xsd:complexType to declare an
el-ement with elel-ement content (child elel-ements only), with mixed content (child elements plus character data), or with empty content (neither child elements nor character data) Later in the chapter, you’ll learn how to add attributes to ele-ments with any of these three types of content
Declaring an Element with Element Content
An element declared with element content can contain one or more child
elements of the specified type or types, as well as attributes (if declared, as discussed later) To declare an element with element content, you define the
element’s type using xsd:complexType and include within it a content model that
describes the permissible child elements, the allowed arrangement of these ele-ments, and the rules for their occurrences You create the content model by
using the xsd:sequence, xsd:choice, or xsd:all schema element, or a combination
of these elements Each of these schema elements adds a group of element decla-rations to the content model The meaning of the group depends upon which schema element you use
A group of child elements declared in an xsd:sequence element must appear in
the exact order listed For example, the following declaration of the
MOUN-TAIN element uses xsd:sequence to stipulate that a MOUNMOUN-TAIN element must
contain exactly one NAME, one HEIGHT, and one STATE child element, in that order:
Trang 4178 XML Step by Step
Here’s an example a valid FILM element:
<FILM>
<STAR>Sandra Bullock</STAR>
</FILM>
Again, you can regulate the number of occurrences of a particular child element
by adding a minOccurs or a maxOccurs attribute specification, or both
specifi-cations, to that element’s declaration
Finally, if you declare a group of child elements within an xsd:all schema
element, the child elements can occur in any order By default, each child element must occur exactly once However, you can make a particular child
element optional by including the attribute specification minOccurs="0" in the xsd:element start-tag For an element in an xsd:all group, you can assign the minOccurs or maxOccurs attribute only the value 0 or 1.
For example, the following declaration indicates that the child elements of a MOUNTAIN element can occur in any order The NAME element must appear exactly once The HEIGHT and STATE elements can each appear one time or not at all
<xsd:element name=”MOUNTAIN”>
<xsd:complexType>
<xsd:all>
<xsd:element name=”NAME” type=”xsd:string”/>
<xsd:element name=”HEIGHT” type=”xsd:positiveInteger” minOccurs=”0”/>
<xsd:element name=”STATE” type=”xsd:string”
minOccurs=”0"/>
</xsd:all>
</xsd:complexType>
</xsd:element>
Given this declaration, the following MOUNTAIN element is valid:
<MOUNTAIN>
<STATE>New Mexico</STATE>
<HEIGHT>13161</HEIGHT>
<NAME>Wheeler</NAME>
</MOUNTAIN>
as is this one:
Trang 5As you’ve seen, you can control the occurrences of individual elements within an
xsd:sequence, xsd:choice, or xsd:all group by assigning values—other than the default value of 1—to the minOccurs and maxOccurs attributes of the indi-vidual elements within the group You can also include a minOccurs or
maxOccurs attribute specification within the xsd:sequence, xsd:choice, or xsd:all element itself to control the number of occurrences of the entire group (As with xsd:element elements, the default value of both attributes is 1.) You’ll
see an example of this practice in the declaration of the PARA element given in the next section
Declaring an Element with Mixed Content
An element declared with mixed content can contain any type of character data, interspersed with any child elements that are declared in the type definition To specify a mixed content element, declare the element with element content
ex-actly as described in the previous section, but add the mixed="true" attribute specification to the xsd:complexType element’s start-tag For example, according
to the following declaration, a TITLE element can contain any type of character data before or after its one child element, SUBTITLE:
<xsd:element name=”TITLE”>
<xsd:complexType mixed=”true”>
<xsd:sequence>
<xsd:element name=”SUBTITLE”/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Here’s an example of a valid element:
<TITLE>Moby-Dick <SUBTITLE>Or, The Whale</SUBTITLE></TITLE>
Recall from Chapter 5 that if you declare an element with “mixed content” us-ing a DTD, the specified child elements can occur in any order and with any number of repetitions (zero or more), interspersed with any amount of character data The following schema declaration emulates a mixed content declaration in
a DTD Specifically, it stipulates that a PARA element can contain BOLD, ITALIC, or UNDERLINE child elements in any order and with any number of repetitions (zero or more), interspersed with character data
<xsd:element name=”PARA”>
<xsd:complexType mixed=”true”>
<xsd:choice minOccurs=”0" maxOccurs=”unbounded”>
<xsd:element name=”BOLD” type=”xsd:string”/>
Trang 6Chapter 7 Creating Valid XML Documents Using XML Schemas 181
<xsd:element name=”ITALIC” type=”xsd:string”/>
<xsd:element name=”UNDERLINE” type=”xsd:string”/>
</xsd:choice>
</xsd:complexType>
</xsd:element>
The following is an example of a valid PARA element:
<PARA>A PARA element may contain character data plus any number of nested elements for marking <ITALIC>italic</ITALIC> text,
<BOLD>boldface</BOLD> text, or <UNDERLINE>underlined</UNDERLINE> text These nested elements can be used in any order.</PARA>
Declaring an Element with Empty Content
An element declared with empty content cannot contain either child elements
or character data (It can have attributes if they are declared as explained later
in the chapter.) To specify this type of element, define the element’s type using
the xsd:complexType element, but omit the content model, as shown in the
following example:
<xsd:element name=”BR”>
<xsd:complexType>
</xsd:complexType>
</xsd:element>
The following is a conforming element:
<BR></BR>
as is this one:
<BR/>
note
To declare an element with empty content, be sure to include the empty
xsd:complexType element in the declaration If you omit it, the element you’re declaring will have the xsd:anyType type rather than empty content.
Trang 7Declaring Attributes
You declare an attribute by using the xsd:attribute schema element An attribute
always has a simple type As when you declare a simple-type element, you can declare an attribute either by using a built-in simple type or by defining a new simple type You use a built-in simple type by assigning the type’s name to the
type attribute of the xsd:attribute element You can define a new simple type by including the xsd:simpleType schema element within the xsd:attribute element.
Here’s an example of an attribute declared using the built-in simple type
xsd:positiveInteger:
<xsd:attribute name=”IndexPages” type=”xsd:positiveInteger”/> And here’s an attribute declared with a newly defined type that is derived from
the built-in type xsd:string:
<xsd:attribute name=”Class”>
<xsd:simpleType>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”fictional”/>
<xsd:enumeration value=”documentary”/>
<xsd:enumeration value=”instructional”/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
You can use the same built-in simple types for an attribute that you can use for
an element For a description of some useful built-in simple types, see Table 7-1
on page 169 For a complete list of these types, see the section “2.3 Simple Types” in the “XML Schema Part 0: Primer” page at
http://www.w3.org/TR/xmlschema-0/ And for instructions on using the
xsd:simpleType schema element to define a new simple type for an attribute, see
“Declaring an Element Using a Defined Simple Type” on page 171
In addition to the name and type attributes of the xsd:attribute element, which supply the attribute’s name and simple type, you can include the use attribute to
control the attribute’s occurrence in the element for which it is declared If you
assign use the value optional (the default value), or omit the use attribute, the attribute can be included or left out If you assign the value required, the at-tribute must be included And if you assign the value prohibited, the atat-tribute
can’t be included For example, the following declaration requires that an
InStock attribute specification always be included in the start-tag of the element
for which the attribute is declared:
Trang 8Chapter 7 Creating Valid XML Documents Using XML Schemas 183
<xsd:attribute name=”InStock” type=”xsd:boolean” use=”required”/>
You can use the default attribute to specify a default value for an attribute, as in
this example declaration:
<xsd:attribute name=”PartNum” type=”xsd:string” default=”0-00-0"/>
If the PartNum attribute specification is omitted from the start-tag of the element for which it is declared, the XML processor will pass the value 0-00-0 to the ap-plication If the PartNum attribute specification is included, the processor will pass the specified value Note that to include a default attribute specification in the xsd:attribute element, the use attribute must be set to optional or omitted The fixed attribute provides an alternative to the default attribute, as shown in
this attribute declaration:
<xsd:attribute name=”Priority” type=”xsd:string” fixed=”high”/>
If the Priority attribute specification is omitted from the element’s start-tag, the XML processor will pass the value high to the application (as with the default attribute) If the Priority attribute specification is included, it must have the
value high (and of course, the processor will pass this value to the application) Note that you can’t have both a fixed and a default attribute specification in the same xsd:attribute element.
caution
Keep in mind that a default attribute value, specified using the default or fixed
attribute, won’t be passed to the application (such as a script in an HTML page) unless the XML document is validated against the schema when the document
is loaded, as demonstrated in the validity-testing page given in “Checking an XML Document for Validity Using an XML Schema” on page 400
note
For a description of all xsd:attribute attributes, see the section “3.2.2 XML
Representation of Attribute Declaration Schema Components” in the “XML
Schema Part 1: Structures” page at http://www.w3.org/TR/xmlschema-1/.
To add an attribute to an element declaration, so that the attribute can (or must)
be used with that element, you must place the xsd:attribute schema element
within the element’s content model How you do this depends upon the type of the element, as discussed in the following two sections
Trang 9Adding Attributes to an Element with
Element, Mixed, or Empty Content
To add an attribute to an element with element content, mixed content, or empty content, you simply include the attribute declaration within the
element’s content model inside the xsd:complexType schema element You must, however, include the attribute declaration after any xsd:sequence, xsd:choice, or xsd:all element.
The following is an example of a declaration for an element (FILM) with
ele-ment content that includes a declaration for an attribute (Class) at the end of its
content model:
<xsd:element name=”FILM”>
<xsd:complexType>
<xsd:sequence>
<xsd:element name=”TITLE” type=”xsd:string”/>
<xsd:choice>
<xsd:element name=”STAR” type=”xsd:string”/>
<xsd:element name=”NARRATOR” type=”xsd:string”/>
<xsd:element name=”INSTRUCTOR” type=”xsd:string”/> </xsd:choice>
</xsd:sequence>
<xsd:attribute name=”Class”>
<xsd:simpleType>
<xsd:restriction base=”xsd:string”>
<xsd:enumeration value=”fictional”/>
<xsd:enumeration value=”documentary”/>
<xsd:enumeration value=”instructional”/>
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
Here is a valid FILM element according to this declaration:
<FILM Class=”fictional”>
<TITLE>The Net</TITLE>
<STAR>Sandra Bullock</STAR>
</FILM>
Trang 10Chapter 7 Creating Valid XML Documents Using XML Schemas 185
The following is an example of a declaration for an element with empty content
(IMAGE) that includes a declaration for an attribute (Source) as the only
decla-ration within its content model:
<xsd:element name=”IMAGE”>
<xsd:complexType>
<xsd:attribute name=”Source” type=”xsd:string”
use=”required”/>
</xsd:complexType>
</xsd:element>
Here’s an example of a valid element conforming to this declaration:
<IMAGE Source=”Logo.gif”/>
Adding Attributes to an Element
Containing Character Data Only
Recall that an element with one or more attributes has a complex type, even if the element contains only character data A simple way to assign an attribute to
an element whose content includes only xsd:string type character data is to de-fine the element’s type using xsd:complexType, include the xsd:mixed="true" attribute specification in xsd:complexType to allow the character data, and in-sert the attribute declaration inside xsd:complexType to allow the attribute.
Here’s an example of a declaration:
<xsd:element name=”AUTHOR”>
<xsd:complexType mixed=”true”>
<xsd:attribute name=”Born” type=”xsd:gYear”/>
</xsd:complexType>
</xsd:element>
And here’s a conforming AUTHOR element:
<AUTHOR Born=”1819">Walt Whitman</AUTHOR>
The xsd:mixed="true" attribute specification allows the element to contain char-acter data of an unconstrained type, just like the xsd:string built-in simple type.
You can’t use this method, however, if you want to constrain the character
data—that is, to assign the character data a type other than xsd:string The
method you must use to add an attribute to an element that contains only con-strained character data is fairly logical and consistent with the overall schema model, but is also quite indirect and cumbersome Briefly stated, you must start with a simple type that describes the character data (for example,
xsd:positiveInteger or xsd:date), and then derive from it a new complex type