Stage 3 proposal: Feature #13059a

Provide a way to associate one or more set of independent DITAVAL conditions with a single branch of content in a map.

Champion

Robert D Anderson

Tracking information

Event Date Links
Stage 1 proposal accepted August 2, 2011 (13059 eventually split into 2 parts) https://www.oasis-open.org/apps/org/workgroup/dita/email/archives/201108/msg00004.html
Stage 2 proposal submitted June 3, 2013 HTML: https://www.oasis-open.org/apps/org/workgroup/dita/download.php/49395/latest; DITA: https://www.oasis-open.org/apps/org/workgroup/dita/download.php/49394/latest
Stage 2 proposal discussed discussion before stage 2 completed: May 21, 2013; discussion of stage 2 proposal June 11, 2013 Aggregated minutes: https://www.oasis-open.org/committees/download.php/49823/minutes2013-q12.txt
Stage 2 proposal approved June 18, 2013 Aggregated minutes: https://www.oasis-open.org/committees/download.php/49823/minutes2013-q12.txt
Stage 3 proposal submitted to reviewers November 1, 2013 Kris Eberlein, Eliot Kimber
Stage 3 proposal (this document) submitted December 6, 2013  

Approved technical requirements

Add a new <ditavalref> element that is used to reference a DITAVAL document.

  • When a <ditavalref> element is specified in a map, the conditions from the referenced DITAVAL will be processed for each topic in that branch of the map. The <ditavalref> will also be used for that branch itself, so that if the branch uses a topicref with otherprops="hide", and the <ditavalref> excludes otherprops="hide", that topicref and its children should be removed.
  • When multiple <ditavalref> elements are specified at the same level of a map branch, the content will be copied once per ditaval, with each copy using one of the conditions. For example, if 3 <ditavalref> elements are specified as peers in the same branch, that branch of content should produce three distinct versions of the content, with each version using one of the <ditavalref> elements to set conditions, as described in the previous bullet.
  • When keys or key scopes are used, copying the branch will result in copied keys or key scopes. This proposal provides new elements that can be used to modify the names of keys or key scopes so that each copy may be referenced individually, by adding a specified prefix or suffix to the values.
  • When copies of a topic are created due to the previous function, files may need to be renamed to avoid conflicts. This is not an issue for monolithic formats such as PDF or for systems that may produce dynamic filtered content without predetermined file names. For situations where file names are important, this proposal provides new elements that can be used to control how files are renamed, using a prefix or a suffix. For example, if the DITA document sample.dita is copied, the new elements may be used to ensure that the copies are processed as sample-linux.dita and sample-mac.dita.

Dependencies or interrelated proposals

COMMENTS: INCLUDE IMPLICATIONS OF PROCESSING ORDER

Modified DTDs

New files: ditavalrefDomain.mod, ditavalrefDomain.ent (and equivalent XSD/RNG).

Updated: include the domain in all of the OASIS distributed map document types.

Modified specification documentation

New language spec topics will be placed in a new group for this domain, in the "base" section of the lang spec, as a peer to the groups for Typographic and Utilities elements. New topics for ditavalref, ditavalmeta, and noFileRenaming are included below, following the new grouping topic.

A new topic for the architectural specification will be created to cover this feature; suggest placing it after the existing "Conditional processing (profiling)" topic. That topic is included below.

DITAVAL reference domain

The DITAVAL reference domain is used to reference a DITAVAL file with conditions that apply to only one portion of a content source. It is also used to publish a subset of one content source for multiple audiences.

ditavalref

The <ditavalref> element references a DITAVAL document in order to specify filter conditions that may be used to process only a subset of the content in a map. Additionally, <ditavalref> elements may be used to imply multiple copies of the map branch that contains them, applying a different set of conditions to each copy.

When a <ditavalref> element is included in a map, the conditions in the referenced DITAVAL document are used to filter the other elements in that branch (the parent element that included the <ditavalref>) and the resources referenced within that branch. In the simple case, a map may use <ditavalref> as follows:
<map>
  <title>Simple usage of ditavalref</title>
  <topicref href="sampleBranch.dita" audience="admin">
    <topicmeta><navtitle>Sample branch</navtitle></topicmeta>
    <ditavalref href="conditions.ditaval"/>
    <topicref href="insideBranch.dita" platform="win linux mac"/>
    <!-- ... other topicrefs ... -->
  </topicref>
  <!-- other branches not affected by conditions.ditaval -->
</map>
The filter conditions from conditions.ditaval apply to the following:
  • The <topicref> that references sampleBranch.dita, and all elements within that branch
  • The topic sampleBranch.dita
  • The topic insideBranch.dita
  • All other topics referenced within this branch

When more than one <ditavalref> is specified in the same branch at the same level, the effective result is one copy of the branch for each <ditavalref>. If the sample above contains a reference to otherConditions.ditaval as a peer to the existing <ditavalref>, the rendered version of this map would reflect two copies of "Sample branch", each reflecting the conditions specified in the corresponding DITAVAL document. One copy is created using the conditions in conditions.ditaval while the other copy uses conditions from otherConditions.ditaval.

If DITAVAL conditions are specified at multiple levels within a single branch, conditions at a higher level take precedence. In the following branch, assume alternate rules are specified for the condition audience="novice". In that case, the condition specified in highLevel.ditaval applies to the entire branch.
<topicref href="ancestor.dita">
  <ditavalref href="highLevel.ditaval"/>
  <topicref href="descendent.dita">
    <ditavalref href="lowLevel.ditaval"/>
    <!-- Other topicrefs -->
  </topicref>
</topicref>

Limitations

The following limitations apply when using the <ditavalref> element, which cannot be enforced through the DTD or Schema.

When the use of <ditavalref> results in multiple copies of a branch, resource names within that branch may be controlled with sub-elements of the effective <ditavalref>. For situations where resource names are relevant, it is an error condition for multiple <ditavalref> elements to result in conflicting resource names for different content. Processors MAY recover by using an alternate naming scheme for the conflicting copies. For example, the following map fragment would result in two distinct copies of c.dita using the same file name:
<topicref href="c.dita">
  <ditavalref href="one.ditaval"/>
  <ditavalref href="two.ditaval"/>
</topicref>

Contains

Contains optional <ditavalmeta>

Contained By

(to be generated)

Inheritance

+ map/topicref ditavalref-d/ditavalref 

Example: one <ditavalref> specific to a branch

input.ditamap:
<map>
  <topicref href="intro.dita"/>
  <topicref href="install.dita">
    <ditavalref href="novice.ditaval"/>
    <topicref href="do-stuff.dita"/>
    <topicref href="advanced-stuff.dita" audience="admin"/>
    <!-- more topics -->
  </topicref>
  <!-- Several chapters worth of other material -->
</map>

novice.ditaval:
<val>
  <prop att="audience" val="novice" action="include"/>
  <prop att="audience" val="admin" action="exclude"/>
</val>
If this sample is published, the following processing will take place:
  • The first topic (intro.dita) does not use any of the conditions that are specified in novice.ditaval. It is published normally, potentially using other ditaval conditions that were specified externally.
  • The second topic (install.dita) is filtered first using any external conditions, and is then filtered using the conditions in novice.ditaval.
  • The third topic (do-stuff.dita) is filtered first using any external conditions, and is then filtered using the conditions in novice.ditaval.
  • The fourth topicref (to advanced-stuff.dita) is removed from the map entirely, because it is filtered out with the conditions specified for this branch.

None of the resources filtered by novice.ditaval will be renamed due to the filtering. This ensures that external links to those topics are stable, regardless of whether the DITAVAL is used.

Example: multiple <ditavalref> elements to create multiple branches

input.ditamap:
<map>
  <topicref href="intro.dita"/>
  <topicref href="install.dita">
    <ditavalref href="win.ditaval"/>
    <ditavalref href="mac.ditaval">
      <ditavalmeta><dvr-resourceSuffix>apple</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <ditavalref href="linux.ditaval">
      <ditavalmeta><dvr-resourceSuffix>linux</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <topicref href="do-stuff.dita">
      <topicref href="mac-specific-stuff.dita" platform="mac"/>
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <!-- Several chapters worth of other material -->
</map>

win.ditaval:
<val>
  <prop att="platform" val="win" action="include"/>
  <prop att="platform" val="mac" action="exclude"/>
  <prop att="platform" val="linux" action="exclude"/>
</val>

mac.ditaval:
<val>
  <prop att="platform" val="win" action="exclude"/>
  <prop att="platform" val="mac" action="include"/>
  <prop att="platform" val="linux" action="exclude"/>
</val>

linux.ditaval:
<val>
  <prop att="platform" val="win" action="exclude"/>
  <prop att="platform" val="mac" action="exclude"/>
  <prop att="platform" val="linux" action="include"/>
</val>
When a processor evaluates this markup, it results in three copies of the install branch. The following processing will take place:
  • The first topic (intro.dita) is published normally, potentially using other ditaval conditions that were specified externally.
  • The install branch appears three times, once for each ditaval. The branches are created as follows:
    • The first branch uses the first ditaval file (win.ditaval). Resources use their original names as specified in the map; this is typically best for the most common or default branch. The file "mac-specific-stuff.dita" is removed from this hierarchy based on win.ditaval. The resulting branch, with indenting to show hierarchy, matches the original without the mac topic:
      install.dita
         do-stuff.dita
           ...more topics and nested branches...
         cleanup.dita
    • The second branch uses the second ditaval file (mac.ditaval). Resources are renamed based on the <dvr-resourceSuffix> element. The file "mac-specific-stuff.dita" is included in this hierarchy based on mac.ditaval. The resulting branch, with indenting to show hierarchy, is:
      install-apple.dita
         do-stuff-apple.dita
            mac-specific-stuff-apple.dita
            ...more topics and nested branches...
         cleanup-apple.dita
    • The third branch uses the last ditaval file (linux.ditaval). Resources are renamed based on the <dvr-resourceSuffix> element. The file "mac-specific-stuff.dita" is removed from this hierarchy based on linux.ditaval. The resulting branch, with indenting to show hierarchy, is:
      install-linux.dita
         do-stuff-linux.dita
           ...more topics and nested branches...
         cleanup-linux.dita
This example used three ditaval files to avoid triple maintenance of the install branch in a map; the following map is functionally equivalent, but requires maintaining each branch in parallel:
input.ditamap:
<map>
  <topicref href="intro.dita"/>
  <topicref href="install.dita">
    <ditavalref href="win.ditaval">
      <ditavalmeta><noFileRenaming/></ditavalmeta>
    </ditavalref>
    <topicref href="do-stuff.dita">
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <topicref href="install.dita">
    <ditavalref href="mac.ditaval">
      <ditavalmeta><dvr-resourceSuffix>apple</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <topicref href="do-stuff.dita">
      <topicref href="mac-specific-stuff.dita" platform="mac"/>
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <topicref href="install.dita">
    <ditavalref href="linux.ditaval"/>
    <topicref href="do-stuff.dita">
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <!-- Several chapters worth of other material -->
</map>

Attributes

Name Description Data Type Default Value Required?
href Provides a reference to a DITAVAL document. See **** MISSING FILE **** for general information on the format and processing implications of the href attribute. CDATA #IMPLIED No
format Format of the target document, which should be a DITAVAL document. CDATA ditaval No
processing-role The processing role defaults to "resource-only" for DITAVAL documents, which are only used for processing, and do not contain content. (resource-only) resource-only No

ditavalmeta

The <ditavalmeta> element defines metadata associated with a DITAVAL document used for one branch of a map.

Because the referenced DITAVAL document is used for processing (it is not published as part of the content), metadata inside of <ditavalmeta> is generally informational in nature and does not have an impact on processing. The element is primarily used to specify prefixes and suffixes used to construct effective resource file names, key scope names, and key names within the map branch implied by the parent <ditavalref> element.

Contains

To be generated; contains optional navtitle then any of <dvr-resourcePrefix>, <dvr-resourceSuffix>, <dvr-keyscopePrefix>, <dvr-keyscopeSuffix>, <dvr-keynamePrefix>, or <dvr-keynameSuffix>.

Contained By

ditavalref

Inheritance

+ map/topicmeta ditavalref-d/ditavalmeta

Example

See ditavalref.

Attributes

Name Description Data Type Default Value Required?

dvr-resourcePrefix

The <dvr-resourcePrefix> element specifies the prefix to use when constructing the effective file names of resources referenced from within the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-resourcePrefix> element contributes to the effective file names of resources referenced within the branch such that the effective resource file name starts with the value of the <dvr-resourcePrefix> element.

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-resourcePrefix

Example

If the the <dvr-resourcePrefix> is specified as:
<topicref href="branch-01.dita">
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-resourcePrefix>cond01-</dvr-resourcePrefix>
    </ditavalmeta>
  </ditavalref>
  <topicref href="topics/subtopic-01.dita"/>
</topicref>
then the effective file name of resource "subtopic-01.dita" in the context of the branch implied by the <ditavalref> element is "cond01-subtopic-01.dita", as though the @copy-to attribute had been specified with that value on the topicref to "subtopic-01.dita".

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-resourcePrefix  
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

dvr-resourcePrefix

The <dvr-resourcePrefix> element specifies the prefix to use when constructing the effective file names of resources referenced from within the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-resourcePrefix> element contributes to the effective file names of resources referenced within the branch such that the effective resource file name starts with the value of the <dvr-resourcePrefix> element.

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-resourcePrefix

Example

If the the <dvr-resourcePrefix> is specified as:
<topicref href="branch-01.dita">
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-resourcePrefix>cond01-</dvr-resourcePrefix>
    </ditavalmeta>
  </ditavalref>
  <topicref href="topics/subtopic-01.dita"/>
</topicref>
then the effective file name of resource "subtopic-01.dita" in the context of the branch implied by the <ditavalref> element is "cond01-subtopic-01.dita", as though the @copy-to attribute had been specified with that value on the topicref to "subtopic-01.dita".

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-resourcePrefix  
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

dvr-resourceSuffix

The <dvr-resourceSuffix> element specifies the suffix to use when constructing the effective file names of resources referenced from within the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-resourceSuffix> element contributes to the effective file names of resources referenced within the branch such that the base part of the effective resource file name ends with the value of the <dvr-resourceSuffix> element.

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-resourceSuffix

Example

If the the <dvr-resourceSuffix> is specified as:
<topicref href="branch-01.dita">
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-resourceSuffix>-cond01</dvr-resourceSuffix>
    </ditavalmeta>
  </ditavalref>
  <topicref href="topics/subtopic-01.dita"/>
</topicref>
then the effective file name of resource "subtopic-01.dita" in the context of the branch implied by the <ditavalref> element is "subtopic-01-cond01.dita", as though the @copy-to attribute had been specified with that value on the topicref to "subtopic-01.dita".

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-resourceSuffix  
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

dvr-keyscopePrefix

The <dvr-keyscopePrefix> element specifies the prefix to use when constructing the effective key scope name for the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-keyscopePrefix> element contributes to the effective key scope name of the branch such that the effective key scope name starts with the value of the <dvr-keyscopePrefix> element. Note that if the branch as authored does not specify a @keyscope value, specifying <dvr-keyscopePrefix> results in the branch establishing a key scope where the key scope name consists of at least the value of the <dvr-keyscopePrefix> element (it will also reflect the value of a <dvr-keyscopeSuffix> element if one is specified).

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-keyscopePrefix

Example

If the the <dvr-keyscopePrefix> is specified as:
<topicref keys="branch-01"
    href="branch-01.dita" 
    keyscope="branch-01"
  >
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-keyscopePrefix>cond01-</dvr-keyscopePrefix>
    </ditavalmeta>
  </ditavalref>
  <topicref href="topics/subtopic-01.dita"/>
</topicref>
then the effective key scope name for the branch "branch-01" is "cond01-branch-01".

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-keyscopePrefix  
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

dvr-keyscopeSuffix

The <dvr-keyscopeSuffix> element specifies the suffix to use when constructing the effective key scope name for the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-keyscopeSuffix> element contributes to the effective key scope name of the branch such that the effective key scope name ends with the value of the <dvr-keyscopeSuffix> element. Note that if the branch as authored does not specify a @keyscope value, specifying <dvr-keyscopeSuffix> results in the branch establishing a key scope where the key scope name consists of at least the value of the <dvr-keyscopeSuffix> element (it will also reflect the value of a <dvr-keyscopePrefix> element if one is specified).

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-keyscopeSuffix

Example

If the the <dvr-keyscopeSuffix> is specified as:
<topicref keys="branch-01"
    href="branch-01.dita" 
    keyscope="branch-01"
  >
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-keyscopeSuffix>-cond01</dvr-keyscopeSuffix>
    </ditavalmeta>
  </ditavalref>
  <topicref href="topics/subtopic-01.dita"/>
</topicref>
then the effective key scope name for the branch "branch-01" is "branch-01-cond01".

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-keyscopeSuffix  
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

dvr-keynamePrefix

The <dvr-keynamePrefix> element specifies the prefix to use when constructing the effective key names for key-defining topic references within the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-keynamePrefix> element contributes to the effective key names for keys defined within the branch such that the effective key names start with the value of the <dvr-keynamePrefix> element. Topic references that do not specify @keys are not affected.

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-keynamePrefix

Example

If the the <dvr-keynamePrefix> is specified as:
<topicref keys="branch-01"
    href="branch-01.dita" 
    keyscope="branch-01"
  >
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-keynamePrefix>cond01-</dvr-keynamePrefix>
    </ditavalmeta>
  </ditavalref>
  <topicref 
    keys="branch01-subtopic-01"
    href="topics/subtopic-01.dita"/>
</topicref>
then the effective key names for the two key-defining topicrefs in the branch are "cond01-branch-01" and "cond01-branch01-subtopic-01", respectively.

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-keynamePrefix no
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

dvr-keynameSuffix

The <dvr-keynameSuffix> element specifies the suffix to use when constructing the effective key names for key-defining topic references in the map branch implied by the ancestor <ditavalref> element.

For map branches implied by <ditavalref> elements, the value of the <dvr-keynameSuffix> element contributes to the effective key names of topicrefs within the branch such that the effective key names end with the value of the <dvr-keynameSuffix> element. Topic references that do not specify @keys are not affected.

Contains

text content or <text>

Contained By

ditavalmeta

Inheritance

+ topic/data ditavalref-d/dvr-keynameSuffix

Example

If the the <dvr-keynameSuffix> is specified as:
<topicref keys="branch-01"
    href="branch-01.dita" 
    keyscope="branch-01"
  >
  <ditavalref href="condition-01.ditaval">
    <ditavalmeta>
      <dvr-keynameSuffix>-cond01</dvr-keynameSuffix>
    </ditavalmeta>
  </ditavalref>
  <topicref 
    keys="branch-01-subtopic-01"
    href="topics/subtopic-01.dita"/>
</topicref>
then the effective key names for the two key-defining topicrefs in the branch are "branch-01-cond01" and "branch01-subtopic-01-cond01", respectively.

Attributes

Name Description Data Type Default Value Required?
name The name of the metadata item string dvr-keynameSuffix  
univ-atts Universal attribute group      
global-atts global (debug) attribute group      
class standard class attribute      

Conditional processing (profiling) on a subset of content

The DITAVAL format provides a way to specify a set of conditions that are used to conditionally process DITA content. While these conditions are often stored outside of the content and applied globally by a processor, the <ditavalref> element may be used to reference a DITAVAL document in order to filter only a subset of content within a map. This also provides the ability to process a single branch of content multiple times, while applying unique conditions to each instance the branch. If a separate set of DITAVAL conditions is applied globally to the content, those take precedence over any conditions specified within a DITAVAL referenced by <ditavalref>.

There are two primary situations where <ditavalref> is intended to help manage conditional processing:
  1. Typically, a set of DITAVAL conditions is applied globally within a content set. In some cases, there is a need to apply specific conditions to one subset of information, which do not apply elsewhere. This may be especially useful when mixing content from different sources, where the author may not have control over the conditions specified in part of the content. In this case, the <ditavalref> element may be used to selectively filter a subset of the overall content, without affecting the rest of the content.
  2. In some cases, a set of content may contain a large amount of information common to all users, along with a subset that varies based on conditions such as audience or platform. In this case, there is often a need to repeat that subset once for each audience. For example, a set of software documentation may contain information that is almost always common to every user, along with installation instructions that vary by operating system. With <ditavalref>, it is possible to define the sequence of installation instructions once while publishing unique copies specific to each operating system (among the common information, which is not repeated).

In the second case, a fully resolved view of the map contains multiple instances of a single branch of content. This may result in duplicate keys, duplicate key scopes, and URIs that specify the same resource with conflicting conditions. Metadata inside of the <ditavalref> is available to provide control over these values, so that keys, key scopes, and URIs may be individually referenced within a branch. This means that processors MUST understand the result of this branch filtering process before they can establish the complete key space for a map.

One or more <ditavalref> elements may appear as a child of the <map>, which results in the filters being applied to the entire map. Using the <ditavalref> as a child of a reference to a map (such as within <mapref>) is similar, and results in the conditions being applied to the referenced map; see samples of both usages below.

It is an error if following these rules results in conflicting copies of a result document with the same name; see sample error conditions below.

Example: one <ditavalref> specific to a branch

input.ditamap:
<map>
  <topicref href="intro.dita"/>
  <topicref href="install.dita">
    <ditavalref href="novice.ditaval"/>
    <topicref href="do-stuff.dita"/>
    <topicref href="advanced-stuff.dita" audience="admin"/>
    <!-- more topics -->
  </topicref>
  <!-- Several chapters worth of other material -->
</map>

novice.ditaval:
<val>
  <prop att="audience" val="novice" action="include"/>
  <prop att="audience" val="admin" action="exclude"/>
</val>
If this sample is published, the following processing will take place:
  • The first topic (intro.dita) does not use any of the conditions that are specified in novice.ditaval. It is published normally, potentially using other ditaval conditions that were specified externally.
  • The second topic (install.dita) is filtered first using any external conditions, and is then filtered using the conditions in novice.ditaval.
  • The third topic (do-stuff.dita) is filtered first using any external conditions, and is then filtered using the conditions in novice.ditaval.
  • The fourth topicref (to advanced-stuff.dita) is removed from the map entirely, because it is filtered out with the conditions specified for this branch.

None of the resources filtered by novice.ditaval will be renamed due to the filtering. This ensures that external links to those topics are stable, regardless of whether the DITAVAL is used.

Example: multiple <ditavalref> elements to create multiple branches

input.ditamap:
<map>
  <topicref href="intro.dita"/>
  <topicref href="install.dita">
    <ditavalref href="win.ditaval"/>
    <ditavalref href="mac.ditaval">
      <ditavalmeta><dvr-resourceSuffix>apple</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <ditavalref href="linux.ditaval">
      <ditavalmeta><dvr-resourceSuffix>linux</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <topicref href="do-stuff.dita">
      <topicref href="mac-specific-stuff.dita" platform="mac"/>
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <!-- Several chapters worth of other material -->
</map>

win.ditaval:
<val>
  <prop att="platform" val="win" action="include"/>
  <prop att="platform" val="mac" action="exclude"/>
  <prop att="platform" val="linux" action="exclude"/>
</val>

mac.ditaval:
<val>
  <prop att="platform" val="win" action="exclude"/>
  <prop att="platform" val="mac" action="include"/>
  <prop att="platform" val="linux" action="exclude"/>
</val>

linux.ditaval:
<val>
  <prop att="platform" val="win" action="exclude"/>
  <prop att="platform" val="mac" action="exclude"/>
  <prop att="platform" val="linux" action="include"/>
</val>
When a processor evaluates this markup, it results in three copies of the install branch. The following processing will take place:
  • The first topic (intro.dita) is published normally, potentially using other ditaval conditions that were specified externally.
  • The install branch appears three times, once for each ditaval. The branches are created as follows:
    • The first branch uses the first ditaval file (win.ditaval). Resources use their original names as specified in the map; this is typically best for the most common or default branch. The file "mac-specific-stuff.dita" is removed from this hierarchy based on win.ditaval. The resulting branch, with indenting to show hierarchy, matches the original without the mac topic:
      install.dita
         do-stuff.dita
           ...more topics and nested branches...
         cleanup.dita
    • The second branch uses the second ditaval file (mac.ditaval). Resources are renamed based on the <dvr-resourceSuffix> element. The file "mac-specific-stuff.dita" is included in this hierarchy based on mac.ditaval. The resulting branch, with indenting to show hierarchy, is:
      install-apple.dita
         do-stuff-apple.dita
            mac-specific-stuff-apple.dita
            ...more topics and nested branches...
         cleanup-apple.dita
    • The third branch uses the last ditaval file (linux.ditaval). Resources are renamed based on the <dvr-resourceSuffix> element. The file "mac-specific-stuff.dita" is removed from this hierarchy based on linux.ditaval. The resulting branch, with indenting to show hierarchy, is:
      install-linux.dita
         do-stuff-linux.dita
           ...more topics and nested branches...
         cleanup-linux.dita
This example used three ditaval files to avoid triple maintenance of the install branch in a map; the following map is functionally equivalent, but requires maintaining each branch in parallel:
input.ditamap:
<map>
  <topicref href="intro.dita"/>
  <topicref href="install.dita">
    <ditavalref href="win.ditaval">
      <ditavalmeta><noFileRenaming/></ditavalmeta>
    </ditavalref>
    <topicref href="do-stuff.dita">
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <topicref href="install.dita">
    <ditavalref href="mac.ditaval">
      <ditavalmeta><dvr-resourceSuffix>apple</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <topicref href="do-stuff.dita">
      <topicref href="mac-specific-stuff.dita" platform="mac"/>
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <topicref href="install.dita">
    <ditavalref href="linux.ditaval"/>
    <topicref href="do-stuff.dita">
      <!-- more topics and nested branches -->
    </topicref>
    <topicref href="cleanup.dita"/>
  </topicref>
  <!-- Several chapters worth of other material -->
</map>

Example: using <ditavalref> as a child of <map>, or in a reference to a map

The following map is equivalent to processing all contents of the map with the conditions in novice.ditaval. If additional conditions are provided external to the map (such as a parameter to the publication process), those global conditions take precedence.

<map>
  <title>Sample map</title>
  <ditavalref href="novice.ditaval"/>
  <!-- lots of content -->
</map>

Similarly, in the following sample, other.ditamap is pulled into another map. The <ditavalref> indicates that all of the content in other.ditamap should be filtered using the conditions in some.ditaval.

<topicref href="parent.dita">
  <topicref href="other.ditamap" format="ditamap">
    <ditavalref href="some.ditaval"/>
  </topicref>
</topicref>

other.ditamap:
<map>
  <topicref href="nestedTopic1.dita">
    <topicref href="nestedTopic2.dita"/>
  </topicref>
  <topicref href="nestedTopic3.dita"/>
</map>
That usage is functionally equivalent to applying the conditions in some.ditaval to the topics referenced in the nested map. For the purposes of filtering, it could be rewritten as:
<topicref href="parent.dita">
  <topicref>
    <ditavalref href="some.ditaval"/>
    <topicref href="nestedTopic1.dita">
      <topicref href="nestedTopic2.dita"/>
    </topicref>
    <topicref href="nestedTopic3.dita"/>
  </topicref>
</topicref>
For the purposes of filtering, this map could also be rewritten as:
<topicref href="parent.dita">
  <topicref href="nestedTopic1.dita">
    <ditavalref href="some.ditaval"/>
    <topicref href="nestedTopic2.dita"/>
  </topicref>
  <topicref href="nestedTopic3.dita">
    <ditavalref href="some.ditaval"/>
  </topicref>
</topicref>

Example: using <ditavalref> within a branch that already uses <ditavalref>

In the following sample, a set of Operating System conditions applies to installation instructions. Within that common branch, a subset of content applies to different audiences.
<topiref href="install.dita">
  <ditavalref href="linux.ditaval"/>
  <ditavalref href="mac.ditaval">
    <ditavalmeta><dvr-resourceSuffix>mac</dvr-resourceSuffix></ditavalmeta>
  </ditavalref>
  <ditavalref href="win.ditaval">
    <ditavalmeta><dvr-resourceSuffix>win</dvr-resourceSuffix></ditavalmeta>
  </ditavalref>
  <topicref href="perform-install.dita"><!-- other topics--></topicref>
  <topicref href="configure.dita">
    <ditavalref href="novice.ditaval">
      <ditavalmeta><dvr-resourceSuffix>novice</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <ditavalref href="advanced.ditaval">
      <ditavalmeta><dvr-resourceSuffix>admin</dvr-resourceSuffix></ditavalmeta>
    </ditavalref>
    <!-- Other config topics -->
  </topicref>
</topicref>

In this case, the effective map contains three instances of the branch as a whole, as in previous samples. The branches are filtered by operating system.

Within each OS instance, the Configuration sub-branch is repeated - filtered once for novice users, and again for advanced users. As a result, there are actually six instances of the Configuration sub-branch:
  1. The first instance is filtered using the conditions in linux.ditaval and novice.ditaval. For this instance, the resource configure.dita is treated as the resource configure-novice.dita (there is no renaming based on linux.ditaval, and novice.ditaval adds the suffix "novice".
  2. The second instance is filtered using the conditions in linux.ditaval and advanced.ditaval. For this instance, the resource configure.dita is treated as the resource configure-admin.dita.
  3. The third instance is filtered using the conditions in mac.ditaval and novice.ditaval. For this instance, the resource configure.dita is treated as the resource configure-mac-novice.dita (first mac.ditaval adds the suffix "mac", resulting in configure-mac.dita, and then novice.ditaval adds the additional suffix "novice".
  4. The fourth instance is filtered using the conditions in mac.ditaval and advanced.ditaval. For this instance, the resource configure.dita is treated as the resource configure-mac-admin.dita.
  5. The fifth instance is filtered using the conditions in win.ditaval and novice.ditaval. For this instance, the resource configure.dita is treated as the resource configure-win-novice.dita.
  6. The sixth instance is filtered using the conditions in win.ditaval and advanced.ditaval. For this instance, the resource configure.dita is treated as the resource configure-win-admin.dita.

Error condition: multiple non-equivalent copies of the same file copied to the same name

The following sample contains several error conditions that result in name clashes.

<topicref href="a.dita" keys="a">
  <ditavalref href="one.ditaval"/>
  <ditavalref href="two.ditaval"/>
  <topicref href="b.dita" keys="b"/>
</topicref>
<topicref href="a.dita"/>
<topicref href="c.dita" keys="c">
  <ditavalref href="one.ditaval">
    <ditavalmeta>
      <dvr-resourceSuffix>token</dvr-resourceSuffix>
      <dvr-keynameSuffix>token</dvr-keynameSuffix>
    </ditavalmeta>
  </ditavalref>
  <ditavalref href="two.ditaval">
    <ditavalmeta>
      <dvr-resourceSuffix>token</dvr-resourceSuffix>
      <dvr-keynameSuffix>token</dvr-keynameSuffix>
    </ditavalmeta>
  </ditavalref>
</topicref>
In this sample, the effective map that results from evaluating the branch filter conditions will have several clashes. In some cases the same file must be processed with conflicting conditions, using the same URI. In addition, keys are duplicated without renaming, meaning that only the first instance can be referenced. Evaluating the filtered branches in this sample will result in the following equivalent map:
<topicref href="a.dita" keys="a"> <!-- a.dita to be filtered by one.ditaval -->
  <topicref href="b.dita" keys="b"/>  <!-- b.dita to be filtered by one.ditaval -->
</topicref>
<topicref href="a.dita" keys="a"> <!-- a.dita to be filtered by two.ditaval; key "a" ignored -->
  <topicref href="b.dita" keys="b"/>  <!-- b.dita to be filtered by two.ditaval; key "b" ignored -->
</topicref>
<topicref href="a.dita"/>
<topicref href="c-token.dita" keys="c-token"> 
  <!-- c-token.ditaval to be filtered by one.ditaval -->
</topicref>
<topicref href="c-token.dita" keys="c-token"> 
  <!-- c-token.ditaval to be filtered by two.ditaval, key "c-token" ignored -->
</topicref>
As an additional example, in a situation where resource filenames map directly to generated XHTML filenames, this map results in the following conflicts:
  1. a.dita generates a.html using 3 alternate set of conditions -- from one.ditaval, two.ditaval, and no ditaval.
  2. b.dita generates b.html using 2 alternate set of conditions -- from one.ditaval and two.ditaval.
  3. c.dita generates c-token.html using both extra sets of conditions.

In this situation, processors MAY recover by using an alternate naming scheme for the conflicting copies.

Implications of processing order

Because the branch filtering process may result in new or renamed keys, key scopes, or URIs, the full results of the branch filtering process MUST be understood by processors before they can construct the effective map and key space in use for a build.

In general the DITA specification shies away from mandating processing orders for different functions, and publication results may vary slightly by tweaking the order in which processes are carried out. In this case, any DITAVAL conditions specified external to the map, such as with a parameter to a publication process, take precedence over conditions referenced with <ditavalref>. For example, if the value audience="admin" is globally excluded by the publication process, that content will be excluded even from a branch where a <ditavalref> reference attempts to set audience="admin" to "include".

There is explicitly no requirement that global filters and filters specified with <ditavalref> be applied at the same time in a publication process.

Processors should consider the following when determining a processing order for other operations:
  • If links are generated based on the map hierarchy, those links should be created using the renamed keys and URIs that result from the evaluating <ditavalref>, to ensure links are consistent within the modified branches.
  • If conref is resolved in topics before <ditavalref> filter conditoins are evaluated, content applying to multiple audiences may be brought in that can then be selectively filtered by branch. For example, if a set of install steps is pulled in with conref (from outside the branch), it may contain information that is later filtered by platform during the <ditavalref> evaluation - resulting in a copy of the steps specific to each OS. If conref is processed after the <ditavalref>, content may be pulled in that has not been appropriately filtered for the new context.
  • The same scenario applies to conref values that push content into the branch; pushing content prior to resolving the <ditavalref> conditions allows content for multiple conditions to be pushed into the branch, and then filtered by branch based on the <ditavalref> conditions. If the branch using <ditavalref> pushes content elsewhere, resolving <ditavalref> first could result in multiple copies of the content to be pushed (one for each branch), resulting in multiple potentially conflicting copies pushed to the new destination.