prev | table of contents | next |
Although object orientation isn't a key feature of XML or the XML Schema
language, it's still possible to apply the fundamental OO paradigm when
designing a schema: inheritance. This is based on the schema element
xsd:extension
which lets you add both child elements and
attributes to some elsewhere defined type acting as the base type. The example
given below presents the components for defining a simple menu (this time
it's for a graphical user interface) where menu entries may come in several
flavours: simple items, check boxes, radio buttons and sub-menus.
<xsd:complexType name="EntryType"> <xsd:attribute name="Text" type="xsd:string"/> </xsd:complexType> <xsd:complexType name="ItemType"> <xsd:complexContent> <xsd:extension base="EntryType"> <xsd:sequence> <xsd:element name="Command" type="xsd:string"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="CheckBoxType"> <xsd:complexContent> <xsd:extension base="ItemType"> <xsd:attribute name="State" type="xsd:boolean"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="RadioButtonType"> <xsd:complexContent> <xsd:extension base="ItemType"> <xsd:attribute name="Group" type="xsd:string"/> <xsd:attribute name="State" type="xsd:boolean"/> <xsd:attribute name="Value" type="xsd:string"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:complexType name="MenuType"> <xsd:complexContent> <xsd:extension base="EntryType"> <xsd:choice maxOccurs="unbounded"> <xsd:element name="Item" type="ItemType"/> <xsd:element name="CheckBox" type="CheckBoxType"/> <xsd:element name="RadioButton" type="RadioButtonType"/> <xsd:element name="Menu" type="MenuType"/> </xsd:choice> </xsd:extension> </xsd:complexContent> </xsd:complexType>The base class
EntryType
is extended in several ways:
ItemType
adds a command definition to the base type.CheckBoxType
extends ItemType
,
inheriting the command and adding an attribute for the initial state
of the check box.RadioButtonType
is another extension of ItemType
,
again adding some attributes. Group
is the button group's
identification, and Value
defines the string to be used for
indicating the selection.
MenuType
reflects the recursive structure of menus
by being both another subclass of ItemType
(so that it
may represent cascades) as well as a container for all kinds of menu
entries, including itself.MenuType
isn't quite what an OO aficionado would
expect. After all the pains taken to establish this little class
hierarchy, one still must explicitly put all the subclasses into the choice
list. Using just the supertype EntryType
in an
xsd:sequence
would result in very dull menus.
The JAXB compiler, however, rewards you with a set of class definitions
that uses extends
wherever we have xsd:extension
in the schema. A look at the (much abbreviated) code shows the
expected inheritance structure.
public class EntryType { protected String text; // ...(getText, setText) } public class ItemType extends EntryType { protected String command; // ...(getCommand, setCommand) } public class CheckBoxType extends ItemType { protected Boolean state; // ...(isState, setState) } public class RadioButtonType extends ItemType { protected String group; protected Boolean state; protected String value; // ...(getters and setters) }Finally there is
MenuType
, which contains a
java.util.List<EntryType>
. JAXB has briefly reflected upon
the element types bunched into the choice and has, literally,
reverse engineered the common subclass. A reminder that the list is
a mixture is embedded in the name of the getter which is made up
from the first three tags.
public class MenuType extends EntryType { protected List<EntryType> itemOrCheckBoxOrRadioButton; public List<EntryType> getItemOrCheckBoxOrRadioButton() { if (itemOrCheckBoxOrRadioButton == null) { itemOrCheckBoxOrRadioButton = new ArrayList<EntryType>(); } return this.itemOrCheckBoxOrRadioButton; } }
prev | table of contents | next |