Complex Content Elements


In this section we discuss Elements that may have child Elements, that is, those with complex content models. Although it may seem counterintuitive, in some ways these are easier to understand than the simple content Elements discussed in the previous section. One of the reasons for this is that while many features for defining simple content Elements and types are commonly used, relatively few of the features for defining complex content Elements are seen in the wild.

Complex types are specified in Part 1: Structures of the Schema Recommendation. It is, of course, the final source and arbiter of any of these concepts. However, Part 1 is so littered with constraints and validation rules that finding the basic definitions is sometimes a daunting task. Part 0: Primer is usually a better place to start.

Types of Content

In speaking of complex content, we mean an Element that may have other Elements as children. As noted earlier in the chapter, all such elements are of a complex type. Schema language provides several content models, but a single one of them, sequence, is used in nearly all cases in business document schemas. The full set of content models is listed below. There are constraints on the content models beyond what I state here, but these definitions should give you the general idea.

  • sequence : As the name indicates, sequence represents a series of Element children in a specific order. This is by far the most commonly used. If you turn back a few pages to SimpleCSV1.xsd you can see complex types defined with sequence for Row and the root document Element SimpleCSV. The sequence content model is specified by using the xs:sequence Element.

  • choice : This type allows only one of the child Elements to appear in an instance document. Very rare, though I've seen it used a few times. The choice content model is specified by using the xs:choice Element.

  • all : This allows all the child Elements to appear either once and only once or not at all, and it allows them to appear in any order. I've never seen this one used. The all content model is specified by using the xs:all Element.

  • group : This type provides a way to reuse a content model you have defined and named somewhere else. We'll talk more about it later in the chapter. I have yet to see group used either, but as organizations mature in their use of schema language I wouldn't be surprised if group begins to show up. The group content model is specified by using the xs:group Element.

  • mixed : An Element with a mixed content model may have character content in addition to child Elements. Although common in publishing, most people who design business document schemas for documents used directly by applications shun it. The mixed content model is specified by using the mixed Attribute of the xs:complexType or xs:complexContent Elements.

Another feature of schema language that can be a bit confusing is that while a complex type may have complex content, the xs:complexContent Element is not always used when defining complex types. Any of the Elements in the above list may be specified as a child of an xs:complexType Element. The xs:complex Content Element is used only when deriving a new complex type from an existing one by extension or restriction.

With a few exceptions, any of the child Elements specified in these content models may themselves have a complex content model and therefore have children. This is the mechanism whereby we describe nested Elements.

As you can see from the descriptions, some of these content models have explicit constraints on the number of times a child Element may appear. Others don't. The next subsection describes how we specify these constraints.

Mandatory, Optional, Limits

Where records (and occasionally fields or elements in an array) are allowed to repeat in a file, we usually need to set upper boundaries on how often they may appear. In addition, many applications such as EDI allow some data to be optional. We express these constraints in schema language through the minOccurs and maxOccurs Attributes. These are set on the child Elements in the content model. Again, if you turn back to SimpleCSV1.xsd, you can see a minOccurs="0" set on the ColumnXX Elements. Here it is again, in a single Element declaration from the sequence.

 <xs:element name="Column01" type="xs:string" minOccurs="0"/> 

To set a specific limit, we specify the appropriate integer value for the maxOccurs Attribute. An Element with no upper boundary on occurrences is specified with a maxOccurs value of "unbounded", as follows .

 <xs:element name="Row" maxOccurs="unbounded"> 

The default for both minOccurs and maxOccurs is "1". Setting minOccurs to "0" is equivalent to saying that the Element is optional, while setting it to "1" (or greater) is equivalent to saying that it is mandatory.

There are other constraints on maxOccurs depending on the content model. For sequence (the most common) and choice, the maxOccurs value may be any integer value greater than or equal to zero, or the string "unbounded". This means that an Element may be declared so as to allow it to occur any number of times. For the all content model, maxOccurs may only be "0" or "1"; an Element in this content model may appear once at most or not at all.

Creating New Complex Types by Extension

One of the nicer features of schema language is the ability to create a new complex type by extending an existing one. The most frequent usage involves taking an existing sequence of Elements and adding a new one at the end. The example below defines RowType, followed by an extension where we add a new column for birth date. You can find the complete schema in SimpleCSV5.xsd.

Extending a Complex Type by Adding an Element in SimpleCSV5.xsd
 <xs:complexType name="RowType">   <xs:annotation>     <xs:documentation>Here we give a named type to our Row         Element, instead of defining it anonymously in-line.     </xs:documentation>   </xs:annotation>   <xs:sequence>    <xs:element name="Column01" type="ColumnType" minOccurs="0"/>    <xs:element name="Column02" type="ColumnType" minOccurs="0"/>    <xs:element name="Column03" type="ColumnType" minOccurs="0"/>    <xs:element name="Column04" type="ColumnType" minOccurs="0"/>    <xs:element name="Column05" type="ColumnType" minOccurs="0"/>    <xs:element name="Column06" type="ColumnType" minOccurs="0"/>    <xs:element name="Column07" type="ColumnType" minOccurs="0"/>    <xs:element name="Column08" type="ColumnType" minOccurs="0"/>    <xs:element name="Column09" type="ColumnType" minOccurs="0"/>    <xs:element name="Column10" type="ColumnType" minOccurs="0"/>   </xs:sequence> </xs:complexType> <xs:complexType name="RowWithBirthDateType">   <xs:annotation>     <xs:documentation>We extend RowType with a column for the         birth date     </xs:documentation>   </xs:annotation>   <xs:complexContent>     <xs:extension base="RowType">      <xs:sequence>       <xs:element name="Column11" type="xs:date" minOccurs="0"/>      </xs:sequence>     </xs:extension>   </xs:complexContent> </xs:complexType> 

People most commonly use this approach when creating their schemas after performing object-oriented analysis. Deriving complex types by adding Elements is very similar to extending base classes into subclasses with additional properties or methods .

Attribute Declarations

Elements with complex content can have Attributes in the same way that Elements with simple content can. If we wanted to add to our Row Element a RowNumber Attribute with the following format:

 <Row RowNumber="2"> 

we could specify the Attribute in our RowType as shown below.

Specifying an Attribute on an Element with Complex Content in SimpleCSV6.xsd
 <xs:complexType name="RowType">   <xs:annotation>     <xs:documentation>Here we give a named type to our Row         Element, instead of defining it anonymously in-line.         We also have added a RowNumber Attribute.     </xs:documentation>   </xs:annotation>   <xs:sequence>    <xs:element name="Column01" type="ColumnType" minOccurs="0"/>    <xs:element name="Column02" type="ColumnType" minOccurs="0"/>    <xs:element name="Column03" type="ColumnType" minOccurs="0"/>    <xs:element name="Column04" type="ColumnType" minOccurs="0"/>    <xs:element name="Column05" type="ColumnType" minOccurs="0"/>    <xs:element name="Column06" type="ColumnType" minOccurs="0"/>    <xs:element name="Column07" type="ColumnType" minOccurs="0"/>    <xs:element name="Column08" type="ColumnType" minOccurs="0"/>    <xs:element name="Column09" type="ColumnType" minOccurs="0"/>    <xs:element name="Column10" type="ColumnType" minOccurs="0"/>   </xs:sequence>   <xs:attribute name="RowNumber" type="xs:integer"     use="optional"/> </xs:complexType> 

You can examine the full schema for this in SimpleCSV6.xsd.



Using XML with Legacy Business Applications
Using XML with Legacy Business Applications
ISBN: 0321154940
EAN: 2147483647
Year: 2003
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net