Table of contents
Appendices
|
2.2 Complex Type Definitions, Element & Attribute DeclarationsComplex Type Definitions, Element & Attribute Declarations
In XML Schema, there is a basic difference between complex
types which allow elements in their content and may carry
attributes, and simple types which cannot have element
content and cannot carry attributes. There is also a major
distinction between definitions which create new types
(both simple and complex), and declarations which enable
elements and attributes with specific names and types (both
simple and complex) to appear in document instances. In
this section, we focus on defining complex types and
declaring the elements and attributes that appear within
them.
ref2New complex types are defined using
the
complexType element and such definitions
typically contain a set of element declarations, element
references, and attribute declarations. The declarations
are not themselves types, but rather an association between
a name and the constraints which govern the appearance of that
name in documents governed by the associated schema.
Elements are declared using the element element, and
attributes are declared using the attribute element. For
example, USAddress is defined as a complex
type, and within the definition of USAddress
we see five element declarations and one attribute
declaration:
NOTE:
Defining the USAddress Type
<xsd:complexType name="USAddress" >
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="state" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
<xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
ref3The consequence of this definition is
that any element appearing in an instance whose type is
declared to be USAddress (e.g.
shipTo in
po.xml) must consist of five elements and one
attribute. These elements must be called name,
street, city, state
and zip as specified by the values of the
declarations' name attributes, and the
elements must appear in the same sequence (order) in which
they are declared. The first four of these elements will
each contain a string, and the fifth will contain a
number. The element whose type is declared to be
USAddress may appear with an attribute called
country which must contain the string
US.
ref4The USAddress definition
contains only declarations involving the simple types: string,
decimal and
NMTOKEN. In contrast, the
PurchaseOrderType definition contains element
declarations involving complex types, e.g.
USAddress, although note that both declarations use
the same type
attribute to identify the type, regardless of whether the
type is simple or complex.
NOTE:
Defining PurchaseOrderType
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="USAddress"/>
<xsd:element name="billTo" type="USAddress"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
In defining PurchaseOrderType, two of the
element declarations, for shipTo and
billTo, associate different element names with the
same complex type, namely USAddress. The
consequence of this definition is that any element
appearing in an instance document (e.g.
po.xml) whose type is declared to be
PurchaseOrderType must consist of elements named
shipTo and billTo, each
containing the five subelements (name,
street, city, state and
zip) that were declared as part of
USAddress. The shipTo and
billTo elements may also carry the
country attribute that was declared as part of
USAddress.
The PurchaseOrderType definition contains an
orderDate attribute declaration which, like
the country attribute declaration, identifies
a simple type. In fact, all attribute declarations must
reference simple types because, unlike element
declarations, attributes cannot contain other elements or
other attributes.
ref5The element declarations we have
described so far have each associated a name with an
existing type definition. Sometimes it is preferable to use
an existing element rather than declare a new element, for
example:
NOTE:
<xsd:element ref="comment" minOccurs="0"/>
This declaration references an existing element,
comment, that was declared elsewhere in the purchase
order schema. In general, the value of the ref attribute must reference a
global element, i.e. one that has been declared under
schema rather
than as part of a complex type definition. The consequence
of this declaration is that an element called
comment may appear in an instance document, and its
content must be consistent with that element's type, in
this case, string.
Occurrence Constraints[top]
Occurrence Constraints
ref6The comment element is
optional within PurchaseOrderType because the
value of the
minOccurs attribute in its declaration is 0. In
general, an element is required to appear when the value of
minOccurs
is 1 or more. The maximum number of times an element may
appear is determined by the value of a maxOccurs attribute in
its declaration. This value may be a positive integer such
as 41, or the term unbounded to indicate there
is no maximum number of occurrences. The default value for
both the
minOccurs and the maxOccurs attributes is
1. Thus, when an element such as comment is
declared without a
maxOccurs attribute, the element may not occur
more than once. Be sure that if you specify a value for
only the
minOccurs attribute, it is less than or equal to
the default value of
maxOccurs, i.e. it is 0 or 1. Similarly, if you
specify a value for only the maxOccurs attribute, it
must be greater than or equal to the default value of
minOccurs,
i.e. 1 or more. If both attributes are omitted, the element
must appear exactly once.
ref36Attributes may appear once or not at
all, but no other number of times, and so the
syntax for specifying
occurrences of attributes is different than the syntax for
elements. In particular, attributes can be declared with a
use attribute
to indicate whether the attribute is
required (see for example, the partNum
attribute declaration in
po.xsd), optional, or even
prohibited.
Default values of both attributes and elements are declared using the
default attribute, although this attribute has a slightly
different consequence in each case. When an attribute is declared with a
default value, the value of the attribute is whatever value
appears as the attribute's value in an instance document; if
the attribute does not appear in the instance document, the schema
processor provides the attribute with a value equal to that of the
default attribute.
Note that default values for attributes only make sense if the
attributes themselves are optional, and so it is an error to specify
both a default value and anything other than a value of
optional for use.
The schema processor treats defaulted elements slightly differently.
When an element is declared with a default value, the value of the
element is whatever value appears as the element's content in the
instance document; if the element appears without any content, the
schema processor provides the element with a value equal to that of the
default attribute.
However, if the element does not appear in the instance document, the schema
processor does not provide the element at all. In summary, the
differences between element and attribute defaults can be stated as:
Default attribute values apply when attributes are missing, and default
element values apply when elements are empty.
ref55
The fixed attribute is used in both attribute and element
declarations to ensure that the attributes and elements are
set to particular values. For example, po.xsd
contains a declaration for the country
attribute, which is declared with a fixed value US. This
declaration means that the appearance of a country
attribute in an instance document is optional (the default value of
use is optional),
although if the attribute does appear, its value must be US,
and if the attribute does not appear, the schema processor will provide
a country attribute with the value US. Note
that the concepts of a fixed value and a default value are mutually
exclusive, and so it is an error for a declaration to contain both
fixed and default attributes.
The values of the attributes used in element and attribute
declarations to constrain their occurrences are summarized in
Table 1.
cardinalityTable2100%occurrence constraints
Table 1. Occurrence Constraints for Elements and Attributes
Notes
| center11(1, 1) -, - |
center11required, -, - |
11element/attribute must appear once, it may have any value |
| center11(1, 1) 37, - |
center11required, 37, - |
11element/attribute must appear once, its value must be 37 |
| center11(2, unbounded) 37, - |
center11n/a |
11element must appear twice or more, its value must be
37; in general,
minOccurs and
maxOccurs values may be positive integers, and
maxOccurs value
may also be "unbounded" |
| center11(0, 1) -, - |
center11optional, -, - |
11element/attribute may appear once, it may have any value |
| center11(0, 1) 37, - |
center11n/a |
11element may appear once, if it does not
appear it is not provided; if it does appear and it is empty, its
value is 37; if it does appear and it is not empty,
its value must be 37 |
| center11(0, 1) 37, -n/a |
center11optional, 37, - |
11element/attribute may appear once, if it does appear
its value must be 37, if it does not appear its value is 37 |
| center11(0, 1) -, 37 |
center11n/a |
11element may appear once; if it does not
appear it is not provided; if it does
appear and it is empty, its value is 37; otherwise its value is that
given |
| center11(0, 1) -, 37n/a |
center11optional, -, 37 |
11element/attribute may appear once; if it does not
appear its value is 37, otherwise its value is that given |
| center11(0, 2) -, 37 |
center11n/a |
11element may appear once, twice, or not at all; if the
element does not appear it is not provided; if it does
appear and it is empty, its value is 37; otherwise its
value is that given; in general, minOccurs and maxOccurs values may be
positive integers, and maxOccurs value may also
be "unbounded" |
| center11(0, 0) -, - |
center11prohibited, -, - |
11element/attribute must not appear |
| 31
Note that neither
minOccurs,
maxOccurs, nor use
may appear in the declarations of global elements and
attributes. |
Global Elements & Attributes[top]
Global Elements & Attributes
Global elements, and global attributes, are created by
declarations that appear as the children of the schema element. Once
declared, a global element or a global attribute can be
referenced in one or more declarations using the ref attribute as described
above. A declaration that references a global element
enables the referenced element to appear in the instance
document in the context of the referencing declaration. So, for
example, the comment element appears in
po.xml at the same level as
the shipTo, billTo and
items elements because the declaration that
references comment appears in the complex type
definition at the same level as the declarations of the
other three elements.
The declaration of a global element also enables the
element to appear at the top-level of an instance document.
Hence purchaseOrder, which is declared as a
global element in
po.xsd, can appear as the top-level element in
po.xml. Note that this
rationale will also allow a comment element to
appear as the top-level element in a document like
po.xml.
There are a number of caveats concerning the use of
global elements and attributes. One caveat is that global
declarations cannot contain references; global declarations
must identify simple and complex types directly. Put
concretely, global declarations cannot contain the ref attribute, they must
use the type
attribute (or, as we describe shortly, be followed by an anonymous type definition). A
second caveat is that cardinality constraints cannot be
placed on global declarations, although they can be placed
on local declarations that reference global declarations.
In other words, global declarations cannot contain the
attributes minOccurs, maxOccurs, or use.
Naming Conflicts[top]
Naming Conflicts
We have now described how to define new complex types
(e.g. PurchaseOrderType), declare elements
(e.g. purchaseOrder) and declare attributes
(e.g. orderDate). These activities generally
involve naming, and so the question naturally arises: What
happens if we give two things the same name? The answer
depends upon the two things in question, although in
general the more similar are the two things, the more
likely there will be a conflict.
Here are some examples to illustrate when same names cause
problems. If the two things are both types, say we define a
complex type called USStates and a simple type called
USStates, there is a conflict. If the two things are a type
and an element or attribute, say we define a complex type
called USAddress and we declare an element called USAddress,
there is no conflict. If the two things are elements within
different types (i.e. not global elements), say we declare
one element called name as part of the USAddress type and a
second element called name as part of the Item type, there
is no conflict. (Such elements are sometimes called local
element declarations.) Finally, if the two things are both
types and you define one and XML Schema has defined the
other, say you define a simple type called decimal, there
is no conflict. The reason for the apparent contradiction
in the last example is that the two types belong to
different namespaces. We explore the use of namespaces
in schema in a later section.
|