DTDs

A well-formed document (the last lesson's rules) just means the XML syntax is correct. A DTD — Document Type Definition — goes a step further, defining exactly which elements and attributes are allowed to appear, and in what order, so a document can be checked against a specific structure.

Well-formed vs. valid

A document can be perfectly well-formed and still contain data that makes no sense for its purpose — a <book> with a <price> of "banana", or missing a <title> entirely. A DTD lets you define the rules that catch that: which child elements each element is allowed to have, how many times, and in what order. A document that follows those rules is called valid, not just well-formed.

Declaring elements

A DTD uses <!ELEMENT> declarations to describe each element's allowed content:

DTD book.dtd
<!ELEMENT book (title, author, year)>
<!ELEMENT title (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT year (#PCDATA)>

This says a <book> must contain exactly one <title>, one <author>, and one <year>, in that order — and each of those three is #PCDATA, meaning it holds plain text rather than further child elements.

Declaring attributes

<!ATTLIST> declares which attributes an element can carry, and whether each one is required:

DTD adding an attribute rule
<!ATTLIST book id CDATA #REQUIRED>

This says every <book> element must carry an id attribute, holding character data (CDATA), and that it's required (#REQUIRED) — a document missing it would be well-formed but not valid against this DTD.

Connecting a document to its DTD

A document references its DTD with a <!DOCTYPE> declaration, either pointing at an external .dtd file or defining the rules inline:

XML book.xml, referencing an external DTD
<?xml version="1.0"?>
<!DOCTYPE book SYSTEM "book.dtd">
<book id="42">
  <title>Dune</title>
  <author>Frank Herbert</author>
  <year>1965</year>
</book>

A validating parser reads book.dtd, checks this document against those rules, and reports an error if anything's missing, out of order, or extra.

Note: DTDs are the original way to validate XML, but they have real limitations — they can't express data types (a DTD can't say "this must be a number"), and their syntax is unlike XML itself. XML Schema (XSD) came later specifically to fix these gaps, and is the more common choice for new work — but DTDs are still common in older and legacy XML formats, which is why it's worth recognizing one when you see it.