Conditional processing
Conditional processing
Conditional processing is the filtering or flagging of information based on processing-time criteria. Conditional processing is based on attributes specified in the DITA source.
About conditional processing
Certain concepts are critical for a full understanding of conditional processing.
- conditional processing
- A process that determines whether content is included, excluded, or flagged. This process is based on a comparison of conditional-processing attributes in the DITA source with the rules that are set in one or more DITAVAL documents.
- conditional processing attribute
-
Attributes that can be used for filtering and flagging. These are the following attributes:
@props
and any attribute specialized from@props
, including those integrated by default in the OASIS-provided document-type shells:@audience
,@deliveryTarget
,@platform
,@product
,@otherprops
- The
@rev
attribute, which supports flagging but not filtering
- conditional-processing profile
- A set of rules that are provided to a processor for use at rendering time. These rules are based on one or more DITAVAL documents.
- DITAVAL document
- A document that specifies a set of rules that define which elements to include, exclude, or flag. A DITAVAL document can be a file on the file system, a set of rules stored in memory, or another way of storing information that is expressed using DITAVAL syntax.
- filtering
- The process of excluding content at rendering time.
- flagging
- The process of emphasizing content by inserting images, text, or stylistic formatting at rendering time.
Expectations for conditional processing
Certain behaviors are expected of processors when working with conditional processing.
Processors SHOULD be able to perform filtering and
flagging using the following attributes: @props
,
@audience
, @deliveryTarget
,
@platform
, @product
, and
@otherprops
.
The @props
attribute can be specialized to create new attributes, and
processors SHOULD be able to perform conditional
processing on specializations of @props
.
Although metadata elements exist with similar names, such as the
<audience>
element, the specification does not define any
mechanism for conditional processing using metadata elements.
About the DITAVAL document
A DITAVAL document specifies a set of rules that defines which elements to include, exclude, or flag.
The markup for DITAVAL documents provides a standard way to define all conditional processing that is associated with the DITA specification.
- Defines a rendering behavior for an attribute and value
pair, for example,
audience="novice"
. - Defines a default behavior for a conditional processing attribute, such as
defining a default rendering behavior of exclude for the
@deliveryTarget
. With that default, any@deliveryTarget
value not otherwise defined in the document uses that default behavior of exclude. - Defines a default behavior for all conditional processing attributes, such as defining a default rendering behavior of exclude. With that default, any conditional-processing attribute not otherwise defined in the document uses that default behavior of exclude.
While the DITAVAL markup is not part of the DITA topic or map vocabulary and cannot be specialized, the XML itself is part of the specification. See DITAVAL elements for details.
Conditional processing attribute values
Conditional processing attributes use space-delimited string values or grouped string values to support both filtering and flagging.
The simplest and most common way to specify metadata on a conditional processing attribute is
using individual string values. For example, the values
basic and deluxe within <p product="basic
deluxe">
indicate that the paragraph applies to the basic and deluxe
products.
Setting a conditional processing attribute to an empty value, such as
product=""
, is equivalent to omitting that attribute from the element.
Conditional processing attribute values with groups
For more advanced needs, groups can be used to organize metadata into subcategories within a conditional processing attribute.
Grouped values are intended to support situations where a metadata attribute applies to
multiple specialized subcategories. For example, if content is
classified into two distinct types of product, those distinct types can become named groups
within the @product
attribute. The grouping syntax exactly matches the
syntax used for generalized attributes, making it valid inside @props
and any
attribute specialized from @props
, including
those integrated by default in the OASIS-provided document-type
shells: @audience
,
@deliveryTarget
, @platform
,
@product
,
@otherprops
.
The following rules apply to groups within conditional processing attributes:
- Groups consist of a name immediately followed by a parenthetical group of zero or more
space-delimited string values. For example,
"groupName(valueOne valueTwo)"
. - Groups cannot be nested.
- If two groups with the same name are found in a single attribute, they are treated as if
all values are specified in the same group. The following values for the
@otherprops
attribute are equivalent:otherprops="groupA(a b) groupA(c) groupZ(APPNAME)" otherprops="groupA(a b c) groupZ(APPNAME)"
- If both grouped values and ungrouped values are found in a single attribute, the ungrouped
values belong to an implicit group; the name of that group matches the name of the
attribute. Therefore, the following values for the
@product
attribute are equivalent:product="a database(dbA dbB) b appserver(mySERVER) c" product="product(a b c) database(dbA dbB) appserver(mySERVER)"
An empty group within an attribute is equivalent to omitting that group from the attribute.
For example, <ph product="database() A">
is equivalent to <ph
product="A">
. Similarly, <ph product="operatingSystem()">
is
equivalent to <ph product="">
, which in turn is equivalent to
<ph>
.
If two groups with the same name exist on different attributes, a rule specified for that
group will evaluate the same way on each attribute. For example, if the group "sample" is
specified within both @platform
and @otherprops
, a DITAVAL
rule for sample="value"
will evaluate the same in each attribute.
If there is a need to distinguish between similarly named groups on different attributes, the
best practice is to use more specific group names such as platformGroupname
and productGroupname. Alternatively, DITAVAL rules can be specified based
on the attribute name rather than the group name.
If the same group name is used in different attributes, a complex scenario could be created
where different defaults are specified for different attributes, with no rule set for a group or
individual value. In this case a value might end up evaluating differently in the different
attributes. For example, a DITAVAL can set a default of "exclude" for @platform
and
a default of "flag" for @product
. If no rules are specified for group
oddgroup()
, or for the value oddgroup="edgecase"
, the attribute
platform="oddgroup(edgecase)"
will evaluate to "exclude" while
product="oddgroup(edgecase)"
will resolve to "flag". See DITAVAL elements for information on how to change default
behaviors in DITAVAL profile.
Conditional processing and subject schemes
When a subject scheme defines controlled values for an attribute, a processor can make use of that scheme for conditional processing.
Filtering based on metadata attributes
When rendering content, a conditional processing profile can be used to specify whether an element's content is filtered based on its conditional processing attributes.
To determine whether content is filtered, a processor compares the conditional processing attributes on a DITA element to rules specified in a conditional processing profile. If any one of the conditional processing attributes evaluates as exclude, that content is filtered.
Within a DITAVAL document, it is possible to specify a default action for conditional
processing attributes. When no default is specified, the processing default for any attribute or
value not otherwise listed is include. For example,
if no default action is provided for @audience
and the value
novice for that attribute is not defined, that attribute value will have a
processing default of include.
When deciding whether to include or exclude a particular element, a processor evaluates each attribute independently:
- For each attribute:
- If the attribute is empty, or contains only empty groups, it is equivalent to omitting the attribute from the element. If evaluated for the purposes of filtering, the attribute is treated as "include", because an omitted attribute cannot evaluate to "exclude".
- If the attribute value does not contain any groups, then if any string token in the attribute value evaluates to include, the element evaluates to include. In other words, the attribute evaluates to exclude only when all string tokens in that attribute evaluate to exclude.
- If the attribute value does include groups, evaluate as follows, treating ungrouped tokens
together as an implicit group:
- For each group (including any implicit group), if any string token inside the group evaluates to include, the group evaluates to include. In other words, a group evaluates to exclude only when all string tokens in that group evaluate to exclude.
- If any group within an attribute evaluates to exclude, that attribute evaluates to exclude. In other words, the attribute evaluates to include only when all groups in that attribute evaluate to include.
- If any single attribute evaluates to exclude, the element is filtered.
For example, if a paragraph applies to three products and the publisher has chosen to exclude all of them, the processor will exclude the paragraph. This is true even if the paragraph applies to an audience or platform that is not excluded. But if the paragraph applies to an additional product that has not been excluded, then its content is still relevant for the intended output and is preserved.
Flagging based on metadata attributes
When rendering content, a conditional processing profile can be used to specify whether an element's content is flagged based on its conditional processing attributes.
For example, flagging can be used to highlight the fact that content applies to a specific audience or operating system. Flagging can also draw a reader's attention to content that has been marked as being revised.
When deciding whether to flag a particular element, a processor evaluates each value. Wherever
an attribute value that has been set as flagged appears (for example,
audience="administrator"
), the processor adds the flag. When multiple flags
apply to a single element, multiple flags are rendered, typically in the order that they are
encountered.
When the same element evaluates as both flagged and included, the element is both flagged and
included. When the same element evaluates as both flagged and filtered (for example, flagged
because of a value for the @audience
attribute and filtered because of a value
for the @product
attribute value), the element is filtered.
When flagging methods are specified for elements at different levels of the containment hierarchy, the flagging method that is specified for the element at the lowest level of the hierarchy applies.
For example, if a
<section>
element is to be flagged with green
text and a <p>
element within that section is to be flagged with red text, the <p>
element should
be rendered with red text.
Examples of conditional processing
This section is non-normative.
This section provides examples that illustrate the ways that conditional processing attributes can be set and used.
Example: Setting conditional processing values
This section is non-normative.
In this scenario, conditional processing attributes are set in DITA content.
<p audience="administrator">Set the configuration options:
<ul>
<li product="extendedProd">Set foo to bar</li>
<li product="basicProd extendedProd">Set your blink rate</li>
<li>Do some other stuff</li>
<li>Do a special thing for Linux</li>
</ul>
</p>
- The entire paragraph and list of options applies to an audience of administrator.
- The first configuration item applies only to the extendedProd product.
- The second configuration option applies to both the baseProd and extendedProd products.
When combined with a DITAVAL document, these attributes can be used as a way to filter or flag the content when it is rendered.
Example: Simple DITAVAL document
This section is non-normative.
In this scenario, a simple DITAVAL document sets up rules for filtering and flagging based on conditional processing attributes.
The following code sample illustrates a simple DITAVAL document that sets up two rules for filtering, and two rules for flagging.
<val>
<prop action="exclude" att="audience" val="advanced"/>
<prop action="exclude" att="product" val="myProductPrime"/>
<prop action="flag" att="product" val="myProduct" backcolor="purple"/>
<revprop action="flag" val="v1.2" backcolor="yellow"/>
</val>
- Any element with
audience="advanced"
will be filtered and will not appear in the rendered content. - Any element with
product="myProductPrime"
will be filtered and will not appear in the rendered content. - Any element with
product="myProduct"
will be flagged with a purple background color. - Any element with
rev="v1.2"
will be flagged with a yellow background color. - All other content will be rendered normally, because any other conditional processing attribute values default to include.
Example: Changing the default behavior to "exclude"
This section is non-normative.
In this scenario, a simple DITAVAL document resets the default behavior for unspecified values to "exclude".
The following code sample illustrates a simple DITAVAL document that resets the default behavior to "exclude", and then defines two rules to include content.
<val>
<prop action="exclude"/>
<prop action="include" att="audience" val="novice"/>
<prop action="include" att="product" val="myProductPrime"/>
</val>
- Any element with
audience="novice"
will be included and will appear in the rendered content. - Any element with
product="myProductPrime"
will be included and will appear in the rendered content. - All other values in conditional processing attributes evaluate to exclude.
As a result, any element with conditional processing attributes that do not match either
audience="novice"
or product="myProductPrime"
will be
filtered and will not appear in the rendered content.
Example: Flagging with @outputclass
This section is non-normative.
In this scenario, the @outputclass
attribute in a DITAVAL document is
used to enable CSS based flagging.
An additional expectation for this scenario is that the processor rendering DITA content
preserves @outputclass
values as CSS @class
tokens in HTML5.
For example, the phrase <ph outputclass="bird">eagle</ph>
might be
rendered in HTML5 as <span class="bird">eagle</span>
.
The following code sample illustrates a simple DITAVAL document that sets up two rules for
flagging using @outputclass
.
<val>
<prop action="flag" att="product" val="myProduct" outputclass="myProductToken"/>
<prop action="flag" att="product" val="myOtherProduct" outputclass="myOtherProductToken"/>
</val>
<ol>
<li>This list item applies to all content</li>
<li product="myProduct">This list item is specific to my product</li>
<li product="myProduct" outputclass="example">This list item is an example of an edge case</li>
<li product="myOtherProduct">This list item is specific to my OTHER product</li>
<li product="myProduct myOtherProduct">This list item is specific to both of my products</li>
</ol>
- The first item does not specify any conditional processing attributes, and is handled normally.
- The second item specifies
product="myProduct"
. Based on the DITAVAL document, this results in a setting onoutputclass="myProductToken"
. The content is processed as if the original element was:<li product="myProduct" outputclass="myProductToken">
. - The third item specifies
product="myProduct"
, but already has an@outputclass
attribute specified in the source. Based on the DITAVAL document, the content is processed as if the original element was:<li product="myProduct" outputclass="myOtherProductToken example">
. Note that the value supplied by the DITAVAL document is placed before any value already in the source. - The fourth item specifies
product="myOtherProduct"
. Based on the DITAVAL document, this results in a setting onoutputclass="myOtherProductToken"
. The content is processed as if the original element was:<li product="myOtherProduct" outputclass="myOtherProductToken">
. - The fifth item specifies both products with
product="myProduct myOtherProduct"
. Based on the DITAVAL document, this results in a setting of eitheroutputclass="myProductToken myOtherProductToken"
oroutputclass="myOtherProductToken myProductToken"
. The order of the two tokens is unspecified; if a processor chooses the first, the content is processed as if the original element was:<li product="myProduct myOtherProduct" outputclass="myProductToken myOtherProductToken">
.
@outputclass
values onto the
HTML @class
attribute, the rendered HTML5 result would look like
this:<ol>
<li>This list item applies to all content</li>
<li class="myProductToken">This list item is specific to my product</li>
<li class="myProductToken example">This list item is an example of an edge case</li>
<li class="myOtherProductToken">This list item is specific to my OTHER product</li>
<li class="myProductToken myOtherProductToken">This list item is specific to both of my products</li>
</ol>
Example: Filtering based on groups
This section is non-normative.
In this scenario, groups are used for filtering within a conditional processing attribute.
<ol>
<li>Common step</li>
<li product="appServer(mySERVER) database(dbOne dbOther)">
<ph>Do something special for databases dbTwo or dbOther when installing on mySERVER</ph>
</li>
<!-- additional list items -->
</ol>
If a publisher decides to exclude the application server mySERVER,
then the appServer()
group evaluates to exclude. This can be done by
setting product="mySERVER"
to exclude or by setting
appServer="mySERVER"
to exclude. This means the item is excluded,
regardless of how the values dbOne or dbOther
evaluate. If a rule is specified for both product="mySERVER"
and
appServer="mySERVER"
, the rule for the more specific group name
"appServer" takes precedence.
Similarly, if both dbOne and dbOther evaluate to
exclude, then the database()
group evaluates to exclude and the element
is excluded regardless of how the "mySERVER" value is set.
product="database"
to "exclude". This is equivalent to setting a
default of "exclude" for any individual value in a database()
group; it
also excludes the more common usage of "database" as a single value within the
@product
attribute. Thus when "myDB" appears in a
database()
group within the @product
attribute, the
full precedence for determining whether to include or exclude the value is as
follows:- Check for a DITAVAL rule for
database="dbOne"
- Check for a DITAVAL rule for
product="dbOne"
- Check for a DITAVAL rule for
product="database"
(default for the database group) - Check for a DITAVAL rule for "product" (default for the
@product
attribute) - Check for a default rule for all conditions (default of include or exclude for all attributes)
- Otherwise, evaluate to "include"
Example: Filtering and flagging topic content
This section is non-normative.
In this scenario, a publisher wants to flag information that applies to administrators and exclude information that applies to the extended product.
Consider the following DITA source fragment and conditional processing profile:
<p audience="administrator">Set the configuration options:
<ul>
<li product="extendedProd">Set foo to bar</li>
<li product="basicProd extendedProd">Set your blink rate</li>
<li>Do some other stuff</li>
<li>Do a special thing for Linux</li>
</ul>
</p>
<val>
<prop att="audience" val="administrator" action="flag">
<startflag><alt-text>ADMIN</alt-text></startflag>
</prop>
<prop att="product" val="extendedProd" action="exclude"/>
</val>
When the content is rendered, the paragraph is flagged, and the first list item is excluded (since it applies to extendedProd). The second list item is still included; even though it does apply to extendedProd, it also applies to basicProd, which was not excluded.
- Set your blink rate
- Do some other stuff
- Do a special thing for Linux
Example: Simple DITAVAL document
This section is non-normative.
A DITAVAL document can reference tokens that pull in additional topics from a subject scheme.
Example: DITAVAL with conditions for groups
This section is non-normative.
In this advanced scenario, grouped values are used for filtewring within a conditional processing attribute.
Example
This section is non-normative.
<val>
<prop action="exclude" att="product" val="appserver"/>
<prop action="include" att="product" val="mySERVER"/>
<prop action="include" att="database" val="dbFIRST"/>
<prop action="include" att="database" val="dbSECOND"/>
<prop action="exclude" att="database" val="newDB"/>
</val>
@product
attribute. In that case, the
sample DITAVAL above performs the following actions:- The first
<prop>
element excludes the value "appServer" when used within the@product
attribute. It also sets a default of "exclude" for values within any appServer() group inside of the@product
attribute. - The second
<prop>
element sets "mySERVER" to include; this applies whether "mySERVER" appears alone in the@product
attribute (product="mySERVER"
) or inside of any group (product="appServer(mySERVER)"
orproduct="otherGroup(mySERVER)"
). - The third and fourth
<prop>
elements set the database values "dbFIRST" and "dbSECOND" to include. If those values appear inside of a "database" group, they are explicitly set to "include". If they appear elsewhere in a conditional attribute (such asproduct="dbFIRST"
orplatform="dbSECOND"
), this rule does not apply. - The final
<prop>
element sets the database value "newDB" to exclude. If that value appears inside of a database group, it is explicitly set to "exclude". If it appears in any other group or attribute, this rule does not apply.
<p product="appServer">
is filtered out, because this value is excluded.<p product="appServer(A B)">
is filtered out, because there is no explicit rule for A or B, and values in the "appServer" group inside of@product
default to exclude.<p product="appServer(A B mySERVER)">
is included, becauseproduct="mySERVER"
evaluates to "include", which means the entire group evaluates to "include".<p product="newDB">
is included, because no rule in the DITAVAL applies, so the "newDB" token defaults to "include".<p product="database(newDB)">
is filtered out, because the token "newDB" is excluded when found in the database group.<p product="database(dbFIRST dbSECOND newDB)">
is included, because both "dbFIRST" and "dbSECOND" are included, so the group evaluates to include.<p product="database(newDB) appserver(mySERVER)">
is filtered out, because the token "newDB" is excluded when found in the database group. The entire "database" group on this paragraph evaluates to "exclude", so the element is excluded, regardless of how the "appServer" group evaluates.
@product
or
@platform
. See Conditional processing for
suggestions on how to handle similar groups on different
attributes.