The Advanced templates with XML article contains a brief introduction to writing DTD files. Here we explore more advanced Document Type Definition composition methods.
Attributes and elements may be forced to contain not just a certain type of data, but a specific value, or set of values. In the next code sample, the sample tag can be set to one of three values, A, B or C. When tags of this type are defined it is cleaner to use attributes than tags. The next element, test contains and attribute letter, which can be set to one of three values in order for the instance of that element to be valid. Note that for the sample tag the values are quoted and for the attribute letter they are not.
When defining multiple attributes you may use a single ATTLIST tag rather one per attribute. See Example 2 for the code.
Additionally there is the ENTITY tag that can be used in DTD files. This tag defines a named variable the contents of which may be reused in the DTD specification. For example if multiple tags contain the name and date attributes, they may be defined as follows.
Code samples 3 and 4 are identical in the definitions they provide, but they do it in very different ways. Example 3 defines two entities, months and commonattr. Months contains the text that would be required to force one of 12 values to be contained in the month attribute, and commonattr lists three attributes that both elements defined by the DTD share. In order to use an entity, it has to be ended with a semicolon, entities may contain other entities as is illustrated in example 3. Defining entities saves time and space, while providing a single source for editing common features across multiple parts of the DTD
The DTD syntax also provides for variation in the content of tags. That is parent tags may contain some clusters of sub-elements. Example 5 defined a tag element that will have either child1 and child2 tags or the child3 tag instead. So both instances of the element tag in example 6 are valid.
As discussed in the Creating DTDs section above, elements can be allowed to appear in different numbers, the same can be done for element sets. See example 7, there the set of sub-elements child1 and child2 can appear in that order zero or more times and the set of elements child3 and child4 can appear one or more times. It is also possible to use the '?' character to specify zero or one instance of a given set.
It is technically possible to use tags that have not only children but also text content. The XML source for that would look like a variation on the code in example 8, the DTD specification is in example 9. While this technique is useful in some cases, an attempt to should be made to avoid using it when it is possible to organize the data into discrete tags as well. This is not always the case. For example the paragraph element in XHTML may contain text and elements such as images and links.
You may also choose to insert the DTD inline with the document. Example 10 illustrates this. This is not recommended since the point of DTDs is to reuse them across multiple documents. If all XML documents link to the DTD instead of including it, a single modification to this DTD will change for all documents using it, rather than making this change in every document individually.
It is also possible to specify default values for element attributes. The following example contains the code required to do this. Any element child that does not explicitly define a value for the attribute name, will assume the value "unnamed".
DTDs largely belong to the HTML era. While very useful to XML composition, there is a project aimed at replacing DTD functionality with an XML functional equivalent. XML Schema from W3C is an XML-based grammar for creating document specifications.