The Fundamentals of DTD Design - What's The Frequency, Bobby? (Page 5 of 8 )
A number of special symbols can be added to an element declaration in order to define its frequency and order, or the frequency and order of its child elements. Here's a quick list:
symbol description
---------------------------------------------------------
+
one
or more occurrence(s)
* zero or more occurrence(s)
? zero or one occurrence(s)
|
choice
If you're familiar with regular expressions, you'll feel right at home with these
symbols - they're almost identical to the symbols used to build regular expression patterns.
Let's take this for a quick spin. Consider the following revised XML document
<?xml version="1.0"?>
<!DOCTYPE weather SYSTEM "weather.dtd">
<weather>
<city>New
York</city>
<high>26</high>
<low>18</low>
<forecast>rain</forecast>
<city>Boston</city>
<forecast>snow</forecast>
<city>London</city>
<high>32</high>
<forecast>sun</forecast>
</weather>
and then take a look at its associated DTD
<!ELEMENT weather (city, high*, low*, forecast)+>
<!ELEMENT city (#PCDATA)>
<!ELEMENT
forecast (#PCDATA)>
<!ELEMENT high (#PCDATA)>
<!ELEMENT low (#PCDATA)>
How did I come up with this? It's simple - you just have to take it step by step.
The first thing to do is allow for more than one "city" block within the "weather" element.
<!ELEMENT weather (city, high, low, forecast)+>
Next, the "high" and "low" elements must be made optional.
<!ELEMENT weather (city, high*, low*, forecast)+>
And Bob's your uncle!
The | operator sets up a list of alternatives, and comes in handy when an element must contain any one of a finite list of alternatives. Consider the following XML document,
<?xml version="1.0"?>
<addressbook>
<record>
<name>John Smith</name>
<street>24,
Main Street</street>
<city>Poodle Springs</city>
<zip>16628</zip>
<country>USA</country>
<tel>
<home>947
3838</home>
</tel>
</record>
<record>
<name>Sherlock Holmes</name>
<tel>
<home>827
3483</home>
</tel>
<fax>
<home>364
2929</home>
</fax>
<email>
<home>holmes@greatdetectives.org</home>
</email>
</record>
<record>
<name>Jane
Doe</name>
<email>
<work>jane@somedomain.com</work>
</email>
</record>
</addressbook>
and take a look at the corresponding DTD, specifically at the declarations for
the "tel", "fax" and "email" elements, which may contain either "home" or "work" nested child elements.
<!ELEMENT addressbook (record+)>
<!ELEMENT record (name, street?, city?,
zip?, country?, tel?, fax?, email?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT
street (#PCDATA)>
<!ELEMENT city (#PCDATA)>
<!ELEMENT country (#PCDATA)>
<!ELEMENT
zip (#PCDATA)>
<!ELEMENT tel (home | work)>
<!ELEMENT fax (home | work)>
<!ELEMENT
email (home | work)>
<!ELEMENT home (#PCDATA)>
<!ELEMENT work (#PCDATA)>
The | operator also comes in handy when defining elements which are of so-called
"mixed" type - they can contain either data or other elements. Here's an example:
<?xml version="1.0"?>
<surrealism>
The elongated <color>blue</color>
<animal>fox</animal> jumped over the
<color>green</color> <vegetable>pumpkin</vegetable>
and morphed into
<personality>Richard VIII</personality>
</surrealism>
Pay close attention to the "surrealism" element, which can contain either character
data or any one of the listed elements:
<!ELEMENT animal (#PCDATA)>
<!ELEMENT color (#PCDATA)>
<!ELEMENT personality
(#PCDATA)>
<!ELEMENT surrealism (#PCDATA | animal | color | personality |
vegetable)*>
<!ELEMENT
vegetable (#PCDATA)>
Obviously, all these symbols can also be combined to create weird and wonderful
rules for the document to follow. An example awaits you at the end of the article...but first, attributes.
Next: Turning Up The Heat >>
More XML Articles
More By Vikram Vaswani, (c) Melonfire