DTD - Conditional Sections in DTDs: INCLUDE and IGNORE
Conditional sections are a feature of XML Document Type Definitions (DTDs) that allow certain parts of a DTD to be either included in or excluded from the DTD while it is being processed. They are particularly useful when the same DTD needs to support different configurations, environments, document versions, or optional declarations.
Conditional sections are generally used in external DTD subsets. They provide a way to control whether a group of declarations should participate in DTD processing. The two keywords used for this purpose are INCLUDE and IGNORE.
1. INCLUDE Conditional Section
An INCLUDE section tells the XML processor that the declarations inside the section should be processed as part of the DTD.
The basic syntax is:
<![ INCLUDE [
declarations
]]>
For example:
<![ INCLUDE [
<!ELEMENT employee (name, department)>
<!ELEMENT department (#PCDATA)>
]]>
Here, the declarations inside the INCLUDE section become part of the DTD. The XML processor reads and processes them normally.
The main advantage of INCLUDE is that it allows a group of related declarations to be enabled together. Instead of removing declarations manually, a DTD designer can control whether an entire section participates in validation.
2. IGNORE Conditional Section
An IGNORE section tells the XML processor to skip the declarations contained within it.
The syntax is:
<![ IGNORE [
declarations
]]>
For example:
<![ IGNORE [
<!ELEMENT employee (name, department, salary)>
<!ELEMENT salary (#PCDATA)>
]]>
The declarations inside this section are ignored by the XML processor. Therefore, they do not become active declarations in the DTD.
This is useful when declarations are temporarily disabled but may need to be restored later. Instead of deleting the declarations, the developer can place them inside an IGNORE section.
3. Why Conditional Sections Are Useful
Consider a large XML application that has different document versions. Some versions may require additional elements while others may not.
For example, one version could require:
<!ELEMENT employee (name, department)>
while another version could require:
<!ELEMENT employee (name, department, salary)>
Conditional sections can help organize these alternative declarations. A particular configuration can determine which section should be active.
This makes the DTD easier to maintain because declarations that are not currently required do not have to be permanently deleted.
4. Conditional Sections and Parameter Entities
Conditional sections become especially powerful when they are combined with parameter entities.
A parameter entity can be used to determine whether a section is included or ignored.
For example:
<!ENTITY % employee-details "INCLUDE">
<![ %employee-details; [
<!ELEMENT salary (#PCDATA)>
]]>
The parameter entity %employee-details; supplies the keyword INCLUDE. Therefore, the declarations inside the conditional section are processed.
If the parameter entity is changed to:
<!ENTITY % employee-details "IGNORE">
the same section becomes:
<![ IGNORE [
<!ELEMENT salary (#PCDATA)>
]]>
and the declarations are ignored.
This technique allows DTD designers to switch groups of declarations on or off without modifying the declarations themselves.
5. INCLUDE Versus IGNORE
The difference between the two can be summarized as follows:
| Feature | INCLUDE | IGNORE |
|---|---|---|
| Declarations processed | Yes | No |
| Declarations become active | Yes | No |
| Useful for enabling declarations | Yes | No |
| Useful for temporarily disabling declarations | No | Yes |
| Can be controlled using parameter entities | Yes | Yes |
The important point is that INCLUDE and IGNORE control whether a section of the DTD participates in processing.
6. Example with a Complete External DTD
Suppose an XML document contains employee information:
<?xml version="1.0"?>
<!DOCTYPE employees SYSTEM "employees.dtd">
<employees>
<employee>
<name>Ravi</name>
<department>IT</department>
</employee>
</employees>
The external DTD could contain:
<!ENTITY % additional-fields "INCLUDE">
<!ELEMENT employees (employee+)>
<!ELEMENT employee (name, department, salary?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT department (#PCDATA)>
<![ %additional-fields; [
<!ELEMENT salary (#PCDATA)>
]]>
Since %additional-fields; contains INCLUDE, the salary declaration is processed.
If the declaration changes to:
<!ENTITY % additional-fields "IGNORE">
the salary declaration is ignored.
This approach can be useful when maintaining different configurations of an XML vocabulary.
7. Important Restrictions
Conditional sections are mainly associated with external DTD subsets. They are not generally used as ordinary conditional programming constructs inside the XML document itself.
The section must also follow the correct DTD syntax. The keywords INCLUDE and IGNORE are not arbitrary labels; they have a specific meaning to the XML processor.
Conditional sections should therefore be used carefully, particularly in complex DTDs containing parameter entities and multiple external files.
8. Practical Applications
Conditional sections can be useful in several situations.
Supporting Different Document Versions
A DTD can contain declarations for different versions of an XML vocabulary, allowing certain groups of declarations to be enabled or disabled.
Managing Optional Features
A large XML vocabulary may contain optional features. Conditional sections can keep feature-specific declarations separate from the core declarations.
Maintaining Large DTDs
Large DTDs can become difficult to manage. Conditional sections allow related declarations to be grouped logically.
Testing DTD Changes
Developers can temporarily place experimental declarations inside an IGNORE section without deleting them from the DTD.
Creating Configurable DTDs
Parameter entities combined with conditional sections can provide a mechanism for selecting different sets of declarations.
9. Key Difference from XML Conditional Processing
It is important not to confuse DTD conditional sections with conditional logic in programming languages.
For example, a programming language might use:
if condition:
execute statement
DTD conditional sections do not execute XML elements or application logic. They only determine whether particular DTD declarations are processed.
Therefore, INCLUDE and IGNORE affect the structure and validation rules defined by the DTD, not the runtime behavior of an XML application.
10. Summary
Conditional sections provide a mechanism for controlling groups of declarations within DTDs. The INCLUDE keyword causes the declarations within a section to be processed, while IGNORE causes them to be skipped. When combined with parameter entities, these sections can make external DTDs configurable and easier to maintain.
The concept is particularly valuable for large or reusable DTDs where different document configurations require different sets of declarations. Understanding INCLUDE, IGNORE, and parameter-entity-based switching is therefore important for working with advanced XML DTD design.