Explainer
DITA Conditional Processing and DITAVAL

The Short Answer
Mark It Once, Decide at Build Time
Conditional processing, which the DITA specification also calls profiling, lets one set of topics serve several audiences, products, platforms, or outputs. You classify elements with metadata attributes. At publish time you supply a conditional processing profile, a DITAVAL file, that says what to do with each value: include it, exclude it, flag it, or pass it through.
It is one of the four mechanisms behind DITA reuse. The other three, maps, keys, and content references, are covered in DITA maps, keys, and conref. This piece goes deeper on the fourth.
The Attributes
What You Can Profile On
DITA 1.3 names six attributes for filtering, available on most elements. The same six, plus @rev, are used for flagging.
- @product
- The product the content is about.
- @platform
- The platform on which the product is deployed.
- @audience
- The intended reader.
- @deliveryTarget
- The intended output, such as html, pdf, or epub. It replaces the deprecated @print.
- @otherprops
- Anything else that needs no semantic name of its own.
- @props
- The generic base that can be specialized into new, named conditions.
Each attribute holds one or more space-delimited values, so product="model-2000 model-3000" means the content applies to both. Values can also be grouped, such as database(dbA dbB), so that independent subcategories inside one attribute are evaluated separately. An empty attribute counts as no attribute.
Worked Example
A Small DITAVAL, Step by Step
Illustrative DITA 1.3 markup. A list in a topic, with conditions on its items:
<ul>
<li product="model-2000">Open the front cover.</li>
<li product="model-2000 model-3000">Check the filter.</li>
<li audience="administrator">Reset the counter.</li>
<li>Close the cover.</li>
</ul>The profile for one particular build:
<val>
<prop att="product" val="model-2000" action="exclude"/>
<prop att="audience" val="administrator" action="flag">
<startflag><alt-text>ADMIN</alt-text></startflag>
</prop>
<prop att="platform" val="linux" action="passthrough"/>
</val>The first item is excluded, because it applies only to the model the profile removes. The second stays: it also applies to model-3000, which was not excluded, and an attribute excludes an element only when every one of its values excludes. The third is included and flagged ADMIN. The fourth carries no conditions and is always included.
The passthrough rule keeps any platform="linux" value in the output stream so a runtime engine can filter later, such as a help portal that shows content by user setting. Other values are removed from the output even though their content stays.
Actions
Include, Exclude, Flag, Passthrough
- include
- The content is in the output. This is the default for any value the profile does not mention.
- exclude
- The content is removed, provided every value in that attribute is excluded. If any one attribute excludes the element, it is excluded.
- flag
- The content is included and marked with a color, style, image, or text. A flag never hides anything, and if the same element is also filtered, the filter wins.
- passthrough
- The content is included and the attribute value is kept in the output for a runtime engine.
A prop with no attribute sets a default for every value, and a prop with an attribute but no value sets the default for that one attribute. A profile that opens by setting the default to exclude turns the model around: only what you list is published.
Controlled Values
Keep the Vocabulary Closed
Attribute values are free text. A subject scheme map can enumerate the allowed values and bind them to an attribute, so a validating processor warns about anything else:
<subjectScheme>
<subjectdef keys="os" navtitle="Operating system">
<subjectdef keys="linux" navtitle="Linux"/>
<subjectdef keys="windows" navtitle="Windows"/>
</subjectdef>
<enumerationdef>
<attributedef name="platform"/>
<subjectdef keyref="os"/>
</enumerationdef>
</subjectScheme>A scheme can also nest values. If Red Hat Linux sits under Linux and the profile excludes Linux, content marked for Red Hat is excluded too. That is useful, and it is also a reason to design the hierarchy before anyone writes a condition.
Maps
Filtering a Branch With ditavalref
A single DITAVAL applied to a whole build is too blunt when only part of a publication varies. A ditavalref element in a map applies a profile to one branch:
<topicref href="install.dita">
<ditavalref href="linux.ditaval"/>
<ditavalref href="windows.ditaval"/>
</topicref>Two peer references imply two copies of the branch, one filtered by each profile, while the rest of the map is untouched. Exclusions win at every level: a global exclude overrides a branch include, and a branch exclude overrides an include set on a smaller part of the branch.
In the DITA Open Toolkit, a profile for the whole build is passed with the args.filter parameter. Several files are allowed, separated by the system path separator, and earlier files take precedence over later ones. Our DITA Open Toolkit guide covers the engine itself.
Reuse vs Variation
How It Differs From Conref and Keyref
| Dimension | Conref and keyref | Conditional processing |
|---|---|---|
| Question it answers | Where does this text come from? | Should this text appear in this deliverable? |
| Mechanism | Conref pulls an element by address; keyref and conkeyref go through a key the map defines. | Profiling attributes on elements, evaluated against a DITAVAL profile. |
| What changes between outputs | Which source an element resolves to. | Whether an element is present at all, or flagged. |
| Typical use | One approved warning, one product name, one shared procedure. | A step that applies to one model, or a paragraph for one audience. |
Reuse says what the text is; conditions say whether it appears. A mature library uses both, and the common failure is using one to do the other's job: conditions to hold alternate wordings of text that should be a shared reference, or references to hold text that is only sometimes true. The broader pattern is in single-source publishing.
Failure Modes
Where It Goes Wrong
- Condition explosion
- Every new product, audience, and platform adds attributes, and every attribute multiplies the ways content can combine. Ten independent yes/no conditions allow 1,024 combinations. When no writer can say what a given reader will see, the model needs fewer, better-named conditions, not more.
- Untestable combinations
- A condition that no profile ever selects is never built, never reviewed, and quietly rots. Decide the deliverables first, list the profile that produces each one, and build and review every one of them before release.
- Undefined values leak in
- By default, a value the profile does not mention evaluates to include. A typo such as modle-2000 is not an error; the content simply ships to everyone. Setting a default of exclude, or binding the values to a subject scheme, turns the silent failure into a visible one.
- Flags mistaken for filters
- Flagging marks content that is still in the output. It does not hide anything. If an element is both flagged and filtered, the filter wins and the content is removed, so a flag cannot be used as a soft exclusion.
- Conditions used as a substitute for structure
- When half of a topic is excluded in every build, it is two topics. Split it, or move the difference into a key, and keep conditions for the cases where text really is shared.
The specification asks processors to report attribute values found in content that have no action in the profile. Read that report on every build; it is the cheapest test the system gives you.
The S1000D Counterpart
DITA Conditions and S1000D Applicability
The same business need, one library serving many configurations, is met in S1000D by applicability. The mechanism is more formal. Our guide to S1000D applicability explains the ACT, CCT, and PCT; the comparison below puts the two side by side.
| Dimension | DITA conditions | S1000D applicability |
|---|---|---|
| Where the vocabulary lives | Attribute values on elements. Free text unless a subject scheme map enumerates them. | The ACT defines the testable product attributes, the CCT the conditions. |
| What describes the real product | A DITAVAL file chosen for the build. | The PCT lists the actual product instances and their values. |
| Controlled vocabulary | Optional: a validating processor can warn on values outside a subject scheme. | Content refers to attributes and conditions defined in the ACT and CCT. |
| Typical result | A deliverable per audience, product, or output. | A filtered view for a specific product configuration. |
If your content must be tied to real product configurations and checked against them, that is a reason to weigh S1000D; see S1000D vs DITA. If the variation is audiences, products, and outputs, DITA conditions are usually enough.
FAQ
Questions We Hear
What is DITA conditional processing?
Marking elements with profiling attributes such as @product, @audience, and @platform, then using a DITAVAL profile at publish time to include, exclude, flag, or pass through the content that carries each value. The specification also calls it profiling.
What is a DITAVAL file?
A conditional processing profile, conventionally saved with a .ditaval extension. Its val root holds prop elements, each naming an attribute and value and an action: include, exclude, passthrough, or flag. A prop with no attribute sets the default for everything else.
What is the difference between filtering and flagging?
Filtering decides whether content is in the output. Flagging adds text, an image, or styling to content that is in the output. When the same element is flagged by one condition and excluded by another, it is excluded.
What does passthrough do?
It keeps the content and preserves the attribute value in the output so a runtime engine can filter later, for example on an individual user's settings. Values not passed through are removed from the output even though the content stays.
How is conditional processing different from conref?
Conref and keyref reuse content by pulling it from a source. Conditional processing varies content by deciding whether it appears. Most libraries use both: shared text through references, and variants through conditions.
Is S1000D applicability the same thing?
It solves the same problem for a different world. Applicability is a formal model, with the ACT, CCT, and PCT, that ties content to real product configurations. DITA conditions are lighter attribute filters that you can bind to controlled values if you choose.
Get In Touch
Get the Conditions Right Before You Scale
Send us a sample of your topics and the variants you publish. We will tell you how many conditions the content really needs.