<!ELEMENT address (name, street+, city, state, zip?)>
<!ATTLIST address type (home|business) #REQUIRED>
Voilà! The first declaration creates an element named
address that contains a name element, one or more
street elements, a city and state element, and an optional zip
element. The address element has a single
attribute, type, that must be specified and can
have a value of either home or
business.
Let's define the name elements first:
<!ELEMENT name (first, middle?, last)>
<!ELEMENT first (#PCDATA)>
<!ELEMENT middle (#PCDATA)>
<!ELEMENT last (#PCDATA)>
The name element also contains other elements: a
first name, an optional middle name, and a last name element, each of
which are defined in the subsequent DTD lines. These three elements
have no nested tags and contain only parsed character data, i.e., the
actual name of the person.
The remaining address elements are easy, too:
<!ELEMENT street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT state (#PCDATA)>
<!ELEMENT zip (#PCDATA)>
<!ATTLIST zip length CDATA "5">
All these elements contain parsed character data. The zip element has
an attribute named length that indicates the
length of the zip code. If the length attribute is
not specified, it is set to 5.