SyntaxStudy
Sign Up
XML External DTDs and Entity Declarations
XML Beginner 1 min read

External DTDs and Entity Declarations

An external DTD is stored in a separate file with the .dtd extension and referenced from the DOCTYPE declaration using a SYSTEM identifier (for local/private DTDs) or a PUBLIC identifier followed by a SYSTEM identifier (for published, registered DTDs). The parser fetches and processes the external DTD as if its contents were inlined. External DTDs make schema reuse easier across multiple documents and separate the schema from the instance. Entity declarations in the DTD allow shorthand substitution of text or external content into the document. A general entity () is used in document content as &name;. A parameter entity () is used within the DTD itself as %name;. Parameter entities are especially powerful for factoring out repeated content model fragments and for conditional sections that enable or disable parts of a DTD based on a flag. External general entities reference content in separate files: . When the parser encounters &chapter1; in the document, it replaces it with the content of that file. This was a historic mechanism for building modular XML documents from parts, though modern practices favour XInclude or application-level assembly. Security note: external entity processing (XXE) is a well-known vulnerability in XML parsers — production parsers should disable external entity resolution unless strictly required.
Example
<!-- bookstore.dtd — external DTD file -->
<!-- (this content would live in bookstore.dtd) -->
<!--
<!ELEMENT bookstore (book+)>
<!ELEMENT book (title, author, year, isbn)>
<!ELEMENT title  (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT year   (#PCDATA)>
<!ELEMENT isbn   (#PCDATA)>
<!ATTLIST book id ID #REQUIRED lang NMTOKEN "en">

<!ENTITY publisher "Acme Press">
<!ENTITY addr      "123 Book Lane, Reading, RG1 1AA">
-->

<!-- ——— XML instance file referencing external DTD ——— -->
<?xml version="1.0" encoding="UTF-8"?>

<!-- PUBLIC identifier + SYSTEM fallback -->
<!DOCTYPE bookstore
    PUBLIC "-//AcmePress//DTD Bookstore 1.0//EN"
    "http://example.com/dtd/bookstore.dtd">

<!--
    Inline internal subset that adds/overrides entities
    and can coexist with external DTD
-->
<!DOCTYPE bookstore SYSTEM "bookstore.dtd" [
    <!ENTITY publisher "Acme Press">
    <!ENTITY addr      "123 Book Lane">

    <!-- Parameter entity: reuse in content models -->
    <!ENTITY % textContent "(#PCDATA)">
    <!ELEMENT note %textContent;>
]>

<bookstore>
    <book id="b001" lang="en">
        <title>XML Essentials</title>
        <author>Jane Author</author>
        <year>2024</year>
        <isbn>978-0-000-00000-0</isbn>
    </book>
    <!-- Using the general entity -->
    <note>Published by &publisher; at &addr;.</note>
</bookstore>