DTD
A Document Type Definition (DTD) is a formal grammar for an XML document. It defines the elements that may appear, how they may be nested, which attributes they may contain, and how often particular elements can occur. XML syntax itself determines whether a document is well-formed; a DTD goes further by establishing whether that document is valid against an agreed-upon structure.
DTDs remain useful in legacy systems, publishing workflows, and lightweight data-exchange formats. They are also an effective way to learn how XML vocabularies and validation work in practice.
A DTD commonly defines four aspects of a document:
- Element vocabulary: The names and content models of permitted elements.
- Document structure: The order, grouping, and occurrence rules for those elements.
- Attributes: Which attributes an element may have, their types, and their defaults.
- Entities: Reusable text or markup fragments that can be referenced from multiple locations.
For example, a DTD can require every invoice element to contain a customer element followed by one or more line-item elements. This prevents a document from using valid XML while departing from the structure expected by downstream systems.
Internal and External DTDs
An internal DTD is embedded directly in the XML document within the square brackets of its DOCTYPE declaration:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE note [
<!ELEMENT note (to, from, heading, body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!LEMENT body (#PCDATA)>
]>
<note>
<to>Alex Morgan</to>
<from>Sam Lee</from>
<heading>Meeting reminder</heading>
<body>The meeting starts at 10:00 tomorrow morning.</body>
</note>
Because the rules travel with the document, an internal DTD is convenient for small, self-contained files.
An external DTD is stored separately and referenced from the DOCTYPE declaration:
<!DOCTYPE note SYSTEM "note.dtd">
The SYSTEM identifier points to a system-specific file. A PUBLIC identifier can also be used when the document needs a standardized public identifier:
<!DOCTYPE note
PUBLIC "-//Example//Note DTD 1.0//EN"
"note.dtd">
External DTDs are preferable when many documents share the same structure. The XML files remain concise, while the contract is maintained in one central location.
Declaring Elements
Every element declaration follows this general form:
<!ELEMENT element-name content-model>
The content model describes what the element may contain. The most common forms are:
(#PCDATA): The element contains character data.EMPTY: The element must be empty.ANY: The element may contain any content. This is flexible but provides little validation value.- A child-element pattern: The element contains other elements according to specified rules.
Consider the following definitions:
<!ELEMENT bookshelf (book+)>
<!ELEMENT book (title, author, price, summary?)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ELEMENT summary (#PCDATA)>
The bookshelf element must contain at least one book. Each book must contain title, author, and price, in that order. The summary element is optional.
Sequence and Choice
The comma represents a required sequence:
(first-name, last-name)
The vertical bar represents a choice:
(letter | email)
Parentheses can group alternatives, allowing more complex models:
((subject, body) | (reference+))
Occurrence Indicators
Three indicators control repetition:
?: The element may occur zero or one time.*: The element may occur zero or more times.+: The element must occur at least once.
For example:
(author, editor?, note*)
requires an author, permits one optional editor, and allows any number of note elements.
Mixed Content
Some elements combine ordinary text with child elements. A mixed-content model uses #PCDATA together with element names:
<!ELEMENT paragraph (#PCDATA | emphasis | link)*>
This permits text and the listed inline elements in any order. Without the *, the content model would not allow repeated occurrences.
Declaring Attributes
Attributes are defined with ATTLIST:
<!ATTLIST book
id ID #REQUIRED
category CDATA "Fiction"
format (hardcover | paperback) "paperback"
>
Each declaration may specify an attribute name, a type, and a default value.
Common attribute types include:
CDATA: General character data without a more specific value restriction.ID: A document-wide unique identifier.IDREF: A reference to anIDdeclared elsewhere in the same document.NMTOKEN: A name-like token without spaces.NOTATION: The name of an unparsed entity declared withNOTATION.
Enumerated attributes restrict values to a fixed set:
<!ATTLIST product
condition (new | used | refurbished) "new">
Default values behave in several ways:
#REQUIREDmeans the attribute must be present.#IMPLIEDmeans no default is supplied and the attribute is optional.#FIXED "value"fixes the attribute to one permitted value.- A literal default, such as
"Fiction", is supplied when the attribute is omitted.
DTD attributes are not strongly typed in the modern sense. Even with ID and enumeration support, most values remain character strings rather than dates, numbers, or other domain-specific types.
Defining Entities
An entity gives a name to reusable content. A general entity is referenced with &name;:
<!ENTITY company "Example Technology Ltd.">
<contract>The agreement is between the client and &company;.</contract>
Parameter entities begin with a percent sign and are used within the DTD itself. They are useful for sharing repeated declaration fragments:
<!ENTITY % metadata "(title, author, publication-date)">
<!ELEMENT article %metadata;>
When the same DTD is used by many documents, entities can reduce duplication and make terminology easier to maintain. However, external entities and recursive entity expansion can introduce security risks. Untrusted DTDs and XML documents should therefore be processed with external-resource restrictions and protections against excessive expansion.
DTDs as Exchange Contracts
A DTD can serve as a formal interface between systems. One team produces XML according to the DTD, while another builds software that expects the same element hierarchy and attribute values. This creates a shared contract that can be checked before business logic runs.
A typical validation workflow is:
- Define the document vocabulary and its structural rules.
- Publish the DTD as a versioned artifact.
- Configure receiving systems to validate incoming XML against it.
- Reject invalid documents or route them to an error queue.
- Review and version the DTD when the exchange format changes.
This approach catches missing elements, incorrect ordering, unexpected attributes, and invalid enumerated values early. It does not replace application-level checks for business rules such as whether a date is realistic or an account has sufficient funds.
Limitations
DTDs are compact and easy to deploy, but they have several important limitations:
- Limited data typing: DTDs cannot natively express integer ranges, date formats, decimal precision, or complex field structures.
- Separate syntax: A DTD is not itself written in XML, so it requires its own grammar and processing rules.
- No native namespace support: DTDs cannot cleanly model namespace-aware vocabularies or distinguish identically named elements in different namespaces.
- Weak reusability: Named complex types, substitution groups, and reusable constraints are limited compared with XML Schema.
- Change propagation: Modifying a shared DTD may affect every document and application that depends on it.
For new projects requiring precise data types, namespaces, modular type definitions, or advanced constraints, XML Schema (XSD) is usually the stronger choice. It uses XML syntax and provides built-in types such as date, decimal, and integer, along with richer composition and identity rules.
DTDs nevertheless remain relevant. They are still used in older XML-based protocols, specialized publishing vocabularies, and systems that value minimal dependencies. HTML also retains a DOCTYPE declaration, although <!DOCTYPE html> in modern HTML does not point to a DTD that performs meaningful document validation.
Choosing Between DTD and XML Schema
A DTD is a practical choice when the document model is small, the validation rules are straightforward, and compatibility with existing XML tooling matters. It is especially effective for defining a compact exchange grammar that several systems already understand.
XML Schema is preferable when the format needs strict typing, namespace support, modular components, or constraints that cannot be expressed cleanly in DTD syntax. In many modern architectures, XSD or another schema-based validation technology provides the stronger long-term foundation.
Regardless of the choice, the key benefit of formal validation is consistency: XML defines how data is represented, while a DTD or schema defines what that representation is allowed to mean.