Abstract:
Create a new element whose content model allows only instances of a single element type.
Problem:
There is an element that needs to be repeated several times at the same level of a documents.
Context:
Multiple elements of the same element type need to appear in the document as siblings of each other. Often metadata about the container needs to be expressed as well. The Collection Element is a logical place to put this metadata. Sometimes, the elements need to be grouped into different categories. Multiple Collection Elements can appear in the document, with each container having elements from one of the sub categories.
Forces:
Groups of identical repeated elements often need some context established so that metadata can be associated with the entire group, or to distinguish between different groups of similar elements.
Solution:
Create a new element type that contains the multiple elements of the same type. The Collection Element is often named by putting a descriptive ending on the contained element name. For example, a Collection Element of authors might be called
AuthorList or
AuthorGroup. Another way of naming the Collection Element is to pluralize the contained element name. For example, a collection of
Stock elements would be named
Stocks.
Examples:
Simple Collection Element
<Portfolio>
<StockList>
<Stock>
<Name>IBM</Name>
<Price>110.25</Price>
</Stock>
<Stock>
<Name>MSFT</Name>
<Price>89.50</Price>
</Stock>
</StockList>
<Bonds>
...
</Bonds>
</Portfolio>
Container Element With Metadata
<KitchenInventory>
<GlassList location="cupboard3">
<Glass type="shot" number="5"/>
<Glass type="highball" number="8"/>
</GlassList>
<MugList>
...
</MugList>
</KitchenInventory>
Multiple Categories of Same Collection
<Portfolio>
<StockList Exchange="NYSE">
<Stock>
<Name>IBM</Name>
<Price>110.25</Price>
</Stock>
</StockList>
<StockList Exchange="NASDAQ">
<Stock>
<Name>MSFT</Name>
<Price>89.50</Price>
</Stock>
<Stock>
<Name>AMZN</Name>
<Price>80.75</Price>
</Stock>
</StockList>
</Portfolio>
In this example the Collection Element was needed to establish a context for the exchange data. Without a collection element, this information would have to be duplicated in every
Stock element.
Discussion:
The resulting structure is often easier to read and process. It does however result in documents that take up more space.
Providing a parent element for a list of elements of the same type allows for the collection to have a context, making it easier to add metadata if needed. This may also make processing and reading the document easier.
If there is a significant metadata for the container, in terms of amount of structure or volume, a
Head-Body would be appropriate to include inside of the Collection Element.
Related Patterns:
This is a specialization of the
Container Element pattern.
Known Uses:
The
DocBook DTD has a OrderedList Element, whose only sub-children can be one or more ListItem elements.