prev table of contents next

2.3.5 Spurious Classes

It's not necessary to define a separate type for a list resulting from a maxOccurs="unbounded" attribute attached to some element if this element occurs in an xsd:sequence group. Given the complex type ItemType, it is possible to define another type, say ItemListType, as a list of items.

<xsd:complexType name="ItemType">
  <xsd:sequence>
    ...
  </xsd:sequence>
</xsd:complexType>

<xsd:complexType name="ItemListType">
  <xsd:sequence>
    <xsd:element name="Items" type="ItemType"
                 minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>
Within some other type definition it is equally possible to use either ItemListType, or ItemType with the attribute maxOccurs="unbounded":
<xsd:complexType name="WrapItemType">
  <xsd:sequence>
    <xsd:element name="Items" type="ItemType" maxOccurs="unbounded"/>
  </xsd:sequence>	
</xsd:complexType>

<xsd:complexType name="WrapItemListType">
  <xsd:sequence>
    <xsd:element name="ItemList" type="ItemListType"/>
  </xsd:sequence>	
</xsd:complexType>
The code for WrapItemType contains a list of ItemType objects, providing immediate access to the list:
public class WrapItemType {
    protected List<ItemType> items;
 
    public List<ItemType> getItems() {
        if (items == null) {
            items = new ArrayList<ItemType>();
        }
        return this.items;
    }
}
With the additional type definition in the schema you get an additional Java class.
public class ItemListType {
    protected List<ItemType> items;

    public List<ItemType> getItems() {
        if (item == null) {
            item = new ArrayList<ItemType>();
        }
        return this.item;
    }
}

public class WrapItemListType {
    protected ItemListType itemList;

    public ItemListType getItemList() {
        return itemList;
    }
    public void setItemList(ItemListType value) {
        this.itemList = value;
    }
}
The additional class layer requires an additional getter call to retrieve an item, e.g., a.getItemList().getItems().

We note that the XML text is verboser, too. The additional type and class requires an additional tag, bracketing the list.

<A>
  <ItemList>
    <Item>...</Item>
    <Item>...</Item>
    ...
  </ItemList>
</A>
This isn't required in the simpler variant:
<B>
  <Item>...</Item>
  <Item>...</Item>
  ...
</B>

Notice, however, that having the <ItemList> element in place has some advantages, too. For one thing, even an empty list of items appears visibly, and may evoke some processing triggered by the empty wrapper element. Also, it is now possible to insert a complete item list in one fell swoop into the parent element, since now there is a setItemList setter. This may help when one object tree is assembled from another one.


prev table of contents next