<!ELEMENT name content> declares an element whose content is EMPTY, ANY, (#PCDATA), mixed (#PCDATA | b)*, or a model of children joined by , (in order) or | (choice) with ?, * and + for occurrence. <!ATTLIST element name type default> declares attributes of type CDATA, an enumeration, ID, IDREF(S), NMTOKEN(S) (name characters, which unlike a name may start with a digit), or the legacy ENTITY and NOTATION; the default is a value, #REQUIRED, #IMPLIED or #FIXED "value". The BookNest catalog as a DTD:
<!ELEMENT catalog (header, book+)> <!ATTLIST catalog xml:lang NMTOKEN #IMPLIED>
<!ELEMENT header (sender, sent, records)>
<!ELEMENT book (identifier, title, contributor+, subject, pages, published, summary,
rating, supply)> <!ATTLIST book id ID #REQUIRED>
<!ELEMENT contributor (name, sort-name)>
<!ATTLIST contributor role (author | editor) #REQUIRED seq CDATA "1">
<!ATTLIST identifier type (sku | isbn13) "sku"> <!ATTLIST subject scheme CDATA #REQUIRED>
<!ELEMENT supply (availability, price)> <!ATTLIST price currency CDATA #FIXED "USD">
<!ELEMENT sender (#PCDATA)> <!ELEMENT sent (#PCDATA)> <!ELEMENT records (#PCDATA)>
<!ELEMENT identifier (#PCDATA)> <!ELEMENT title (#PCDATA)> <!ELEMENT name (#PCDATA)>
<!ELEMENT sort-name (#PCDATA)> <!ELEMENT subject (#PCDATA)> <!ELEMENT pages (#PCDATA)>
<!ELEMENT published (#PCDATA)> <!ELEMENT summary (#PCDATA)> <!ELEMENT rating (#PCDATA)>
<!ELEMENT availability (#PCDATA)> <!ELEMENT price (#PCDATA)>--dtdvalid needs no DOCTYPE in the file but printed only a one-line verdict for the broken copy below (a duplicate ID, an unknown role, a missing rating); a linked DTD with --valid gives details:
xmllint --noout --dtdvalid booknest.dtd booknest-catalog.xml && echo "catalog is valid"
sed -e '1a <!DOCTYPE catalog SYSTEM "booknest.dtd">' -e 's/id="b3"/id="b2"/' \
-e '0,/role="author"/s//role="writer"/' -e '0,/<rating>4.6<\/rating>/s///' \
booknest-catalog.xml > broken.xml
xmllint --noout --valid broken.xml 2>&1 | grep errorcatalog is valid
broken.xml:13: element contributor: validity error : Value "writer" for attribute role of
contributor is not among the enumerated set
broken.xml:27: element book: validity error : Element book content does not follow the DTD,
expecting (identifier , title , contributor+ , subject , pages , published , summary ,
rating , supply), got (identifier title contributor subject pages published summary supply
)
broken.xml:46: element book: validity error : ID b2 already definedEvery leaf is untyped #PCDATA (price could hold "-3"), and names match literally, prefixes included.