The group Element

The group element enables you to group elements in the same way you use parentheses when declaring elements in a DTD. The group element also enables you to create something similar to DTD parameter entities. The order of the elements in the group element can vary as defined by the order attribute.

The declaration for a group element looks like this:

  <!ELEMENT group ((annotation)?, (all | choice | sequence)*)>
  <!ATTLIST group
              minOccurs   CDATA                  '1'
              maxOccurs   CDATA                #IMPLIED
              order       (choice | seq | all)   'seq'
              name        CDATA                #IMPLIED
              ref         CDATA                #IMPLIED
              id            ID                 #IMPLIED>

A group element can optionally contain an annotation element (comments) and must contain an all, a choice, or a sequence element. These elements define the order and usage of the elements in the group, and are examined in detail in the next section. Notice that group elements do not include attributes-they are used only for grouping elements.

The minOccurs and maxOccurs attributes indicate how many times the group element can occur. They replace the markers (*, ?, and +) in the DTD.

The choice, sequence, and all elements

The choice element indicates a choice of elements in the group element-its function is the same as the bar (|) in the DTD. The DTD declaration <!ELEMENT select (optGroup | option )+> would thus become the following schema declaration:

  <group minOccurs = "1" maxOccurs = "*">
          <element ref = "optGroup"/>
          <element ref = "option"/>

The sequence element indicates that the elements must appear in the sequence listed and that each element can occur 0 or more times. When using sequence, you can use minOccurs and maxOccurs as attributes for the elements to specify the number of allowable occurrences of an element element in the group. Using sequence is the same as using the comma separator in the DTD with subgroups that are enclosed in parentheses with occurrence operators. In its simplest form, a sequence element can consist of only one element. For example, the DTD declaration <!ELEMENT optGroup (option )+> would look like this in a schema declaration:

  <group minOccurs = "1" maxOccurs = "*">
          <element ref = "option"/>

The DTD declaration <!ELEMENT ol (font? , li+ )> would look like this as a schema declaration:

  <group >
          <element ref = "font" minOccurs = "0"
                  maxOccurs = "1"/>
          <element ref = "li" minOccurs = "1" maxOccurs = "*"/>

The all element indicates that all the element and group elements listed in the schema must be used, in any order. Each element element in an all group element must have minOccurs and maxOccurs attributes set to 1. The minOccurs and maxOccurs attributes cannot be used for the group element when you are using all; they can be used only for the element elements in the group. A group element declared with order equal to all must not be a subgroup of another group element. For example, because every HTML document must have one and only one head and body, you could declare them in your schema as follows:

  <group >
          <element ref = "head" minOccurs= "1" maxOccurs= "1"/>
          <element ref = "body" minOccurs= "1" maxOccurs= "1"/>

Local embedded groups

When you include the group element declaration within a complexType element, you are embedding the group element declaration inside the complexType element. If you define the group element within the complexType element, that group element is not visible from anywhere else within the schema document-it has local scope. If you are going to use a group element to contain only one element, it makes sense to use a local group.

Wildcards, particles, and compositors

According to the schema specification, the term particle refers to content of an element element that contains only other elements, groups, and wildcards-in other words, no text. Wildcards include several different ways to use the any keyword.

The any keyword in schemas is similar to the ANY keyword in DTDs, except that in a schema any refers only to element and group elements. In a DTD, ANY refers to text and elements. Text content is not part of the any keyword in the schema specification.

One way to reference all element or group elements within the specified namespace and schema as the complexType element is to use the any keyword. If this keyword is used within a complexType element, it indicates that any element or group in the schema in the same namespace as the complexType element could be included within this complextype element. If the value for the namespace is ##targetNamespace, all of the elements within the current document will be used.

Another possibility is to reference all element and group elements in a namespace other than the one the complexType element is in. In this case, you would use the following declaration:

  <any namespace="##name_of_namespace"/>

In a schema, the order element and the minOccurs and maxOccurs attributes together define what is called a compositor. A compositor for a given group element will specify whether elements in the group provide the following conditions:

  • A sequence of the elements that are permitted or required by the specified particles
  • A choice between the elements permitted or required by the specified particles
  • A repeated choice among the elements permitted or required by the specified particles
  • A set of the elements required by the specified particles

A more precise definition can now be created: a group consists of two or more particles plus a compositor.

Document scope groups

Just as you can create complexType elements that have document scope, you can create group elements that have document scope. The same basic rules apply-that is, including a name attribute and declaring the elements as child elements of the schema element. Thus, you could create the following global group elements:

      <group name = "Block" minOccurs = "1" maxOccurs = "*">
              <element ref = "p"/>
              <element ref = "h1"/>
              <element ref = "h2"/>
              <element ref = "h3"/>
              <element ref = "h4"/>
              <element ref = "h5"/>
              <element ref = "h6"/>
              <element ref = "div"/>
              <group >
                      <element ref = "ul"/>
                      <element ref = "ol"/>
              <element ref = "hr"/>
              <element ref = "blockquote"/>
              <element ref = "fieldset"/>
              <element ref = "table"/>
              <element ref = "form"/>
              <element ref = "script"/>
              <element ref = "noscript"/>

This declaration states that any element that uses this group must include at least one of these elements as its content. The content of the element can also be any number of copies of the elements in any order. This declaration is identical to the DTD declaration shown here:

  <!ENTITY % Block " (%block; | form | %misc;)*">
  <!ELEMENT noscript %Block;>

Thus, document scope group elements allow you to create something similar to the parameter entities in DTDs that contained element declarations. You can now use the group element as follows:

  <element name = "noscript">
      <complexType content = "elementOnly">
          <group ref = "Block"/>
          <attributeGroup ref = "attrs"/>
  <element name = "blockquote">
      <complexType content = "elementOnly">
          <group ref = "schemaBlock"/>
          <attributeGroup ref = "attrs"/>
          <attribute name = "cite" type = "string"/>