XML DTD Conditional Sections Using Parameter Entities
This article explains how XML Document Type Definitions (DTDs) use
parameter entities to dynamically toggle conditional validation blocks.
By combining parameter entities with INCLUDE and
IGNORE directives, schema authors can selectively enable or
disable element definitions, attribute lists, and other structural rules
across different XML documents while maintaining a single, reusable DTD
file.
The Mechanism of Conditional Sections
In an external XML DTD, conditional sections control which parts of the DTD the parser processes. These sections use the following syntax:
<![ INCLUDE [ ... ]]>: The parser includes and validates the declarations inside the block.<![ IGNORE [ ... ]]>: The parser skips the declarations inside the block entirely.
When hardcoded, these keywords are static. To make validation
dynamic, the literal keyword (INCLUDE or
IGNORE) is replaced by a parameter entity reference.
Controlling Sections with Parameter Entities
A parameter entity is a variable declared in a DTD using the
% symbol. It can hold a string value representing either
conditional keyword.
1. Declaring the Toggle Entity
Define a parameter entity with the value "INCLUDE" or
"IGNORE":
<!ENTITY % useDraftFeatures "INCLUDE">
<!ENTITY % useProductionFeatures "IGNORE">2. Referencing the Entity in Conditional Blocks
Substitute the keyword in the conditional section header with the
parameter entity reference (%entityName;):
<![ %useDraftFeatures; [
<!ELEMENT notes (#PCDATA)>
<!ATTLIST document reviewStatus CDATA #IMPLIED>
]]>
<![ %useProductionFeatures; [
<!ELEMENT publishedDate (#PCDATA)>
]]>When the XML parser reads the DTD, it expands
%useDraftFeatures; to INCLUDE, making the
notes element valid. Simultaneously,
%useProductionFeatures; expands to IGNORE,
causing the parser to bypass the publishedDate
declaration.
Dynamic Overriding via the Internal DTD Subset
The dynamic power of parameter entities comes from XML’s entity declaration precedence rules: declarations in the internal DTD subset override declarations in the external DTD subset.
An external DTD file (schema.dtd) can set default
values:
<!-- schema.dtd -->
<!ENTITY % debugMode "IGNORE">
<![ %debugMode; [
<!ELEMENT debugInfo (#PCDATA)>
]]>Individual XML document instances can override this default inside
their internal subset (<!DOCTYPE ... [...]>):
<?xml version="1.0"?>
<!DOCTYPE root SYSTEM "schema.dtd" [
<!-- Override the external DTD default -->
<!ENTITY % debugMode "INCLUDE">
]>
<root>
<debugInfo>Diagnostic data here</debugInfo>
</root>Because the internal subset declaration is parsed first,
%debugMode; evaluates to INCLUDE for that
specific XML instance, enabling the debugInfo element
without modifying the shared schema.dtd file.