XML DTD Conditional Sections: INCLUDE and IGNORE
Conditional sections in an XML Document Type Definition (DTD) provide
a mechanism to selectively enable or disable specific markup
declarations. By using the keywords INCLUDE and
IGNORE, schema designers can control which parts of a DTD
are processed by an XML parser. This article explains the purpose of
conditional sections, how INCLUDE and IGNORE
function, and how they are commonly implemented with parameter entities
for modular schema management.
Understanding Conditional Sections
A conditional section is a construct within an external DTD subset that allows declarations to be parsed or skipped based on a defined keyword. They cannot be used in internal DTD subsets.
The basic syntax for a conditional section is:
<![ KEYWORD [
<!-- Markup declarations here -->
]]>The KEYWORD is replaced by either INCLUDE
or IGNORE.
The Purpose of INCLUDE
When a conditional section uses the INCLUDE keyword, the
XML processor treats the declarations within the section normally.
<![ INCLUDE [
<!ELEMENT notes (#PCDATA)>
]]>In this example, the notes element declaration is active
and fully evaluated by the XML parser as part of the document validation
process.
The Purpose of IGNORE
When a conditional section uses the IGNORE keyword, the
XML parser ignores everything between the opening
<![ IGNORE [ and the closing ]]>.
<![ IGNORE [
<!ELEMENT draftComments (#PCDATA)>
]]>In this case, the draftComments declaration is ignored.
It acts similarly to an XML comment, but it allows you to retain
alternative schemas or deprecated rules without permanently deleting
them or manually commenting out complex declaration blocks.
Dynamic Control Using Parameter Entities
The primary utility of conditional sections comes from pairing them
with parameter entities rather than hardcoding INCLUDE or
IGNORE. By referencing a parameter entity as the keyword,
developers can toggle entire sections of a DTD from a single
location.
Example: Switching Between Draft and Production Modes
<!-- Define the switch -->
<!ENTITY % draft "IGNORE">
<!ENTITY % final "INCLUDE">
<!-- Draft-only elements -->
<![ %draft; [
<!ELEMENT reviewStatus (#PCDATA)>
<!ELEMENT internalNotes (#PCDATA)>
]]>
<!-- Production elements -->
<![ %final; [
<!ELEMENT publicationDate (#PCDATA)>
]]>Changing the value of %draft; from "IGNORE"
to "INCLUDE" instantly activates the draft elements across
the entire document without modifying the underlying declarations.
Key Rules and Behaviors
- External Subsets Only: Conditional sections are only recognized in external DTD subsets or external parameter entities.
- Precedence in Nesting: If a conditional section
marked
IGNOREcontains a nested conditional section markedINCLUDE, the outerIGNOREtakes precedence, and the entire block—including the nestedINCLUDE—is ignored. - Character Matching: Within an
IGNOREsection, the parser only scans for nested conditional markers (<![and]]>) to ensure proper closure; normal markup errors inside the ignored block will not halt parser execution.