Branch filtering
Branch filtering
The branch filtering mechanism enables map authors to set filtering conditions for specific branches of a map. This makes it possible for multiple conditional-processing profiles to be applied within a single publication.
Conditional processing profiles are most often used for an entire root map, with rules
applied to all content in that root map. The branch filtering mechanism uses the
<ditavalref>
element to apply rules from a single DITAVAL document
against a subset of content.
The location of the <ditavalref>
element determines the content to
which filtering conditions are applied. The filtering conditions then are used to filter the
map branch itself (that is, the map elements used to create the branch). In addition, it is
used to filter local maps and topics that are referenced by that branch.
The <ditavalref>
element also provides the ability to process a single
branch of content multiple times, applying unique conditions to each instance of the branch.
Overview of branch filtering
Maps or map branches can be filtered by adding a
<ditavalref>
element that specifies the DITAVAL document to use
for that map or map branch.
The <ditavalref>
element is designed to manage conditional
processing for the following use cases.
- A map branch needs to be filtered using conditions that do not apply to the rest of the publication. For example, a root map might contain content that is written for both novice and expert users. However, the authors want to add a section that targets only novice users. Using branch filtering, a map branch can be filtered so that it only includes content germane to a novice audience, while the content of the rest of the map remains appropriate for multiple audiences.
- A map branch needs to be presented differently for different audiences. For example, a set of software documentation might contain installation instructions that differ between operating systems. In that case, the map branch with the installation instructions needs to be filtered multiple times with distinct sets of conditions, while the rest of the map remains common to all operating systems.
In addition to filtering, applications MAY support flagging at the branch level based on the referenced DITAVAL documents.
How filtering rules interact
With branch filtering, it is possible to set include or exclude rules globally, within a map, and within an already filtered map branch. The general rule for conflicts is that once specified, "exclude" conditions are in effect for the entire map or branch.
Filtering rules often are specified globally in a conditional processing profile, outside of the content. When global conditions set a property value to "exclude", that setting overrides any other settings for the same property that are specified at a branch level. Global conditions that set a conditional property to "include" or "flag" do not override branch-level conditions that set the same property to "exclude".
Using <ditavalref>
elements, it is possible to specify one set of
conditions for a branch and another set of conditions for a subset of the branch. As
with global conditions, properties set to "exclude" for a map branch override any other
settings for the same property specified for a subset of the branch. Branch conditions
that set a conditional property to "include" or "flag" do not override conditions on a
subset of the branch that explicitly set the same property to "exclude".
Branch filtering: Single referenced DITAVAL document for a branch
Using a single <ditavalref>
element as a child of a map or map
branch indicates that the map or map branch is filtered using the rules specified in the
referenced DITAVAL document.
The following rules outline how the filtering conditions that are specified in DITAVAL document are applied:
<ditavalref>
element as a direct child of a map- The filtering conditions are applied to the entire map.
<ditavalref>
element within a map branch- The filtering conditions are used to process the entire branch, including the
parent element that contains the
<ditavalref>
element. <ditavalref>
element within a<topicref>
reference to a local map- The filtering conditions are applied to the submap.
<ditavalref>
element within a<topicref>
reference to peer map- The reference conditions are not applied to the peer map.
Branch filtering: Multiple referenced DITAVAL documents for a branch
Using multiple <ditavalref>
elements as the children of a map
or map branch indicates that the map or map branch will be independently filtered using the
rules that are specified in each referenced DITAVAL document.
When multiple <ditavalref>
elements occur as children of the same
element, the rules in the referenced DITAVAL documents are processed independently. This
effectively requires a processor to maintain one copy of the branch for each
<ditavalref>
, so that each copy can be filtered using
different conditions.
<ditavalref>
conditions. However, this might not be the case when multiple
<ditavalref>
elements occur as direct children of a root map.
In this case, it is possible that the map could be filtered in a manner that results in
two or more distinct versions of the <title>
or metadata. How
this is handled is processor dependent. For example, when a
root map has three <ditavalref>
elements as children of
<map>
, a conversion to EPUB could produce an EPUB with
three versions of the content, or it could produce three distinct EPUB
documents.When a processor maintains multiple copies of a branch for different condition sets, it has to manage situations where a single resource with a single key name results in two distinct resources. Key names must be modified in order to allow references to a specific filtered copy of the resource; without renaming, key references could only be used to refer to a single filtered copy of the resource, chosen by the processor. See Branch filtering: Impact on resource and key names for details on how to manage resource names and key names.
Branch filtering: Impact on resource and key names
When map branches are cloned by a processor in order to support multiple condition sets, processors must manage conflicting resource and key names. The DITAVALref domain includes metadata elements that authors can use to specify how resource and key names are renamed.
<ditavalref>
element.When a map branch uses multiple condition sets, processors create multiple effective
copies of the branch to support the different conditions. This results in potential
conflicts for resource names, key names, and key scopes. Metadata elements inside of the
<ditavalref>
element are available to provide control over
these values, so that keys, key scopes, and URIs can be individually referenced within a
branch.
For example, the following map branch references two DITAVAL documents:
<topicref href="productFeatures.dita" keys="features" keyscope="prodFeatures">
<ditavalref href="novice.ditaval"/>
<ditavalref href="admin.ditaval"/>
<topicref href="newFeature.dita" keys="newThing"/>
</topicref>
In this case, the processor has two effective copies of productFeatures.dita and newFeature.dita. One copy of each topic is filtered using the conditions specified in novice.ditaval, and the other copy is filtered using the conditions specified in admin.ditaval.
If an author has referenced a topic using keyref="features"
or
keyref="prodFeatures.features"
, a processor cannot distinguish
which filtered copy is the intended target. The metadata elements in the DITAVALref
domain provide a way to control this scenario.
Using metadata elements in the DITAVAL reference domain
Metadata within the <ditavalref>
element makes it possible to
control changes to resource names and key scope names, so that each distinct filtered copy
can be referenced in a predictable manner.
The DITAVALref domain defines four elements to control URI and key scope values within filtered map branches.
<dvrResourcePrefix>
- The
<dvrResourcePrefix>
element specifies the prefix to use when constructing the effective file names or resource IDs of the resources that are referenced from within the map branch that is implied by the ancestor<ditavalref>
element. This enables a map author to specify a prefix that is added to the start of resource names for each resource in the branch. <dvrResourceSuffix>
- The
<dvrResourceSuffix>
element specifies the prefix to use when constructing the effective file names or resource IDs of the resources that are referenced from within the map branch that is implied by the ancestor<ditavalref>
element. This enables a map author to specify a suffix that is added to the end of resource names (before any extension) for each resource in the branch. <dvrKeyscopePrefix>
- The
<dvrKeyscopePrefix>
element specifies the prefix to use when constructing the effective key scope names for the map branch that is implied by the ancestor<ditavalref>
element. This enables a map author to specify a prefix that is added to the start of key scope names for each key scope in the branch. If no key scope is specified for the branch, this can be used to establish a new key scope, optionally combined with a value specified in<dvrKeyscopeSuffix>
. <dvrKeyscopeSuffix>
- The
<dvrKeyscopeSuffix>
element specifies the suffix to use when constructing the effective key scope names for the map branch that is implied by the ancestor<ditavalref>
element. This enables a map author to specify a suffix that is added to the end of key scope names for each key scope in the branch.
For example, the previous code sample can be modified as follows to create predictable resource names and key scopes for the copy of the branch that is filtered using the conditions that are specified in admin.ditaval.
<topicref href="productFeatures.dita" keys="features" keyscope="prodFeatures">
<ditavalref href="novice.ditaval"/>
<ditavalref href="admin.ditaval">
<ditavalmeta>
<dvrResourcePrefix>admin-</dvrResourcePrefix>
<dvrKeyscopePrefix>adminscope-</dvrKeyscopePrefix>
</ditavalmeta>
</ditavalref>
<topicref href="newFeature.dita" keys="newThing"/>
</topicref>
The novice branch does not use any renaming, which allows it to be treated as the default copy of the branch. As a result, when the topics are filtered using the conditions that are specified in novice.ditaval, the resource names and key names are unmodified, so that references to the original resource name and key name will resolve to topics in the novice copy of the branch. This has the following effect on topics that are filtered using the conditions specified in admin.ditaval:
- The prefix
admin-
is added to the beginning of each resource name in the admin branch.- The resource productFeatures.dita becomes admin-productFeatures.dita
- The resource newFeature.dita becomes admin-newFeature.dita
- The prefix
adminscope-
is added to the existing key scope "prodFeatures".- The attribute value
keyref="adminscope-prodFeatures.features"
refers explicitly to the admin copy of productFeatures.dita - The attribute
keyref="adminscope-prodFeatures.newThing"
refers explicitly to the admin copy of newFeature.dita
- The attribute value
adminscope-prodFeatures.features
will always refer
explicitly to the instance of productFeatures.dita filtered against
the conditions in admin.ditaval, regardless of whether a processor
has performed the filtering yet. References that use the URI
productFeatures.dita or
admin-productFeatures.dita could resolve differently (or fail
to resolve), as discussed in Branch filtering: Implications of processing order.Renaming based on multiple <ditavalref>
elements
It is possible for a branch with <ditavalref>
already in
effect to specify an additional <ditavalref>
, where each
<ditavalref>
includes renaming metadata.
When renaming, metadata on the <ditavalref>
nested more deeply
within the branch appears closer to the original resource or key name. For example:
<topicref href="branchParent.dita">
<ditavalref href="parent.ditaval">
<ditavalmeta>
<dvrResourcePrefix>parentPrefix-</dvrResourcePrefix>
</ditavalmeta>
</ditavalref>
<!-- additional topics or layers of nesting -->
<topicref href="branchChild.dita">
<ditavalref href="child.ditaval">
<ditavalmeta>
<dvrResourcePrefix>childPrefix-</dvrResourcePrefix>
</ditavalmeta>
</ditavalref>
</topicref>
</topicref>
In this situation, the resource branchChild.dita is given a prefix
based on both the reference to parent.ditaval and the reference to
child.ditaval. The value childPrefix- is
specified in the <ditavalref>
that is nested more deeply within
the branch, so it appears closer to the original resource name. The resource
branchChild.dita would result in
parentPrefix-childPrefix-branchChild.dita. Suffixes (if
specified) would be added in a similar manner, resulting in a name like
branchChild-childSuffix-parentSuffix.dita. Note that the
hyphens are part of the specified prefix; they are not added automatically.
Handling resource name conflicts caused by branch filtering
It is possible to construct a root map where the branch filtering mechanism results in resource name conflicts.
It is an error if <ditavalref>
-driven branch cloning results
in multiple copies of a topic that have the same resolved name. Processors SHOULD report an error in such cases. Processors
MAY recover by using an alternate naming
scheme for the conflicting topics.
In rare cases, a single topic might appear in different branches that set different conditions, yet still produce the same result. For example, a topic might appear in both the admin and novice copies of a branch but not contain content that is tailored to either audience; in that case, the filtered copies would match. A processor MAY consider this form of equivalence when determining if two references to the same resource should be reported as an error.
Branch filtering: Implications of processing order
The branch filtering mechanism can result in changes to the global key space for a root map. As a result, processors are required to evaluate branch filtering in order to construct the key space.
The full effects of the branch filtering process MUST be calculated by processors before they construct the effective map and key scope structure. This requirement comes from the fact that the branch filtering process can result in new or renamed keys, key scopes, or URIs that make up the key space.
@keyref
attribute and related attributes are explicitly disallowed on
<ditavalref>
. This prevents any confusion resulting from a
@keyref
that resolves to additional key- or resource-renaming
metadata.In general, the DITA specification refrains from mandating a processing order; thus publication
results can vary slightly depending on the order in which processes are run. With branch
filtering, processors are not required to apply filter conditions specified outside of the map
and filter conditions specified with <ditavalref>
at the same time in a
publishing process.
For example, a processor might use the following processing order:
- Apply externally-specified filter conditions to maps
- Apply filtering based on
<ditavalref>
elements
Because externally-specified "exclude" conditions always take precedence over branch-specific conditions, content excluded based on external conditions will always be removed, regardless of the order in which processors evaluate conditions.
Processors should consider the following points when determining a processing order:
- If links are generated based on the map hierarchy, those links should be created using the
renamed keys and URIs that result from evaluating the
<ditavalref>
filter conditions, to ensure that the links are consistent within the modified branches. For example, sequential links based on a map hierarchy should remain within the appropriate modified branch. - If URI-based content references are resolved in topics before the
<ditavalref>
filtering conditions are evaluated, content that applies to multiple audiences can be brought in and (later in the process) selectively filtered by branch. For example, if a set of installation steps is pulled in with conref (from outside the branch), it might contain information that is later filtered by platform based on<ditavalref>
. This results in copies of the steps that are specific to each operating system. If conref is processed after the<ditavalref>
, content might 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 into a branch before resolving the
<ditavalref>
conditions allows content for multiple conditions to be pushed 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.
- Pushing content into a branch before resolving the
Examples of branch filtering
This section is non-normative.
The branch filtering examples illustrate the processing expectations
for various scenarios that involve <ditavalref>
elements. Processing
examples use either before and after sample markup or expanded syntax that shows the
equivalent markup without the <ditavalref>
elements.
Example: Single <ditavalref>
on a branch
This section is non-normative.
In this scenario, a single <ditavalref>
element is used to
supply filtering conditions for a branch.
Example
This section is non-normative.
Consider the following DITA map and the DITAVAL document that is referenced from the
<ditavalref>
element:
<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>
<val>
<prop att="audience" val="novice" action="include"/>
<prop att="audience" val="admin" action="exclude"/>
</val>
When this content is published, the following processing occurs:
- 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 are specified externally.
- The second topic (install.dita) is filtered using any external conditions as well as the conditions that are specified in novice.ditaval.
- The third topic (do-stuff.dita) is filtered using any external conditions as well as the conditions that are specified in novice.ditaval.
- The fourth topic (advanced-stuff.dita) is removed from the map entirely, because it is filtered out with the conditions that are specified for the branch.
In this example, no resources are renamed based on the
<ditavalref>
processing.
Example: Multiple <ditavalref>
elements on a branch
This section is non-normative.
In this scenario, multiple <ditavalref>
elements are used on a
single map branch to create multiple distinct copies of the branch.
Example
This section is non-normative.
Consider the following DITA map that contains a branch with three peer
<ditavalref>
elements. Because topics in the branch are filtered in
three different ways, processors are effectively required to handle three copies of the
entire branch. Sub-elements within the <ditavalref>
elements are used
to control how new resource names are constructed for two copies of the branch; one copy
(based on the conditions in win.ditaval) is left with the original file
names.
<map>
<topicref href="intro.dita"/>
<!-- Begining of installing branch -->
<topicref href="install.dita">
<ditavalref href="win.ditaval"/>
<ditavalref href="mac.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-apple</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<ditavalref href="linux.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-linux</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<topicref href="do-stuff.dita">
<!-- more topics and nested branches -->
<topicref href="mac-specific-stuff.dita" platform="mac"/>
</topicref>
<!-- End of installing branch -->
<topicref href="cleanup.dita"/>
</topicref>
</map>
<val>
<prop att="platform" val="win" action="include"/>
<prop att="platform" action="exclude"/>
</val>
<val>
<prop att="platform" val="mac" action="include"/>
<prop att="platform" action="exclude"/>
</val>
<val>
<prop att="platform" val="linux" action="include"/>
<prop att="platform" action="exclude"/>
</val>
- The first topic (intro.dita) is published normally, potentially using any other DITAVAL conditions that are specified externally.
- The installing branch appears three times, once for each DITAVAL document. The
branches are created as follows:
- The first branch uses the first DITAVAL document
(win.ditaval). Resources use their original names as specified
in the map. The mac-specific-stuff.dita topic is removed. The
resulting branch, with indenting to show the 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 document
(mac.ditaval). Resources are renamed based on the
<dvrResourceSuffix>
element. The mac-specific-stuff.dita topic is included. The resulting branch, with indenting to show the hierarchy, is as follows: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 document
(linux.ditaval). Resources are renamed based on the
<dvrResourceSuffix>
element. The mac-specific-stuff.dita topic is removed. The resulting branch, with indenting to show the hierarchy, is as follows:install-linux.dita do-stuff-linux.dita ...more topics and nested branches... cleanup-linux.dita
- The first branch uses the first DITAVAL document
(win.ditaval). Resources use their original names as specified
in the map. The mac-specific-stuff.dita topic is removed. The
resulting branch, with indenting to show the hierarchy, matches the original without
the mac topic:
The example used three DITAVAL documents to avoid triple maintenance of the installing branch in a map; the following map is functionally equivalent, but it requires parallel maintenance of each branch.
<map>
<topicref href="intro.dita"/>
<!-- Windows installing branch -->
<topicref href="install.dita">
<ditavalref href="win.ditaval"/>
<topicref href="do-stuff.dita">
<!-- more topics and nested branches -->
</topicref>
<topicref href="cleanup.dita"/>
</topicref>
<!-- Mac installing branch -->
<topicref href="install.dita">
<ditavalref href="mac.ditaval">
<ditavalmeta><dvrResourceSuffix>-apple</dvrResourceSuffix></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>
<!-- Linux installing branch -->
<topicref href="install.dita">
<ditavalref href="linux.ditaval">
<ditavalmeta><dvrResourceSuffix>-linux</dvrResourceSuffix></ditavalmeta>
</ditavalref>
<topicref href="do-stuff.dita">
<!-- more topics and nested branches -->
</topicref>
<topicref href="cleanup.dita"/>
</topicref>
<!-- Several chapters worth of other material -->
</map>
Example: Single <ditavalref>
as a child of
<map>
This section is non-normative.
In this scenario, a <ditavalref>
element is a direct child of
the <map>
element, which is equivalent to setting global filtering
conditions for the map.
Example
This section is non-normative.
The following map is equivalent to processing all the contents of the map with the conditions in the novice.ditaval document. If additional conditions are provided externally (for example, as a parameter to the publishing process), those conditions take precedence.
<map>
<title>Sample map</title>
<ditavalref href="novice.ditaval"/>
<!-- lots of content -->
</map>
Example: Single <ditavalref>
in a reference to a map
This section is non-normative.
In this scenario, a <ditavalref>
element is used when
referencing a map. This is equivalent to setting filtering conditions for the referenced
map.
Example
This section is non-normative.
In the following example, other.ditamap is referenced by a root map.
The <ditavalref>
element indicates that all of the content in
other.ditamap is filtered using the conditions specified in the
some.ditaval document.
<topicref href="parent.dita">
<topicref href="other.ditamap" format="ditamap">
<ditavalref href="some.ditaval"/>
</topicref>
</topicref>
<map>
<topicref href="nestedTopic1.dita">
<topicref href="nestedTopic2.dita"/>
</topicref>
<topicref href="nestedTopic3.dita"/>
</map>
<topicgroup>
container is used here to ensure filtering is not
applied to parent.dita, as it would not be in the original
example:<topicref href="parent.dita">
<topicgroup>
<ditavalref href="some.ditaval"/>
<topicref href="nestedTopic1.dita">
<topicref href="nestedTopic2.dita"/>
</topicref>
<topicref href="nestedTopic3.dita"/>
</topicgroup>
</topicref>
For the purposes of filtering, this map also could be rewritten as follows.
<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>
Filtering based on the <ditavalref>
element
applies to the containing element and its children, so in each case, the files
nestedTopic1.dita, nestedTopic2.dita, and
nestedTopic3.dita are filtered against the conditions specified in
some.ditaval. In each version, parent.dita is
not a parent for the <ditavalref>
, so it is not filtered.
Example: Multiple <ditavalref>
elements as children of
<map>
in a root map
This section is non-normative.
In this scenario, multiple instances of the <ditavalref>
element
are specified as direct children of the <map>
element in a root map. This
is equivalent to setting multiple sets of global filtering conditions for the root
map.
Example
This section is non-normative.
<ditavalref>
elements as children of the same grouping element. Processing the following root map is equivalent to processing all the contents of the map with the conditions in the mac.ditaval file and again with the linux.ditaval file. If additional conditions are provided externally (for example, as a parameter to the publishing process), those global conditions take precedence.
<map>
<title>Setting up my product
on <keyword platform="mac">Mac</keyword><keyword platform="linux">Linux</keyword></title>
<topicmeta>
<othermeta platform="mac" name="ProductID" content="1234M"/>
<othermeta platform="linux" name="ProductID" content="1234L"/>
</topicmeta>
<ditavalref href="mac.ditaval"/>
<ditavalref href="linux.ditaval"/>
<!-- lots of content, including relationship tables -->
</map>
<val>
<prop att="platform" val="mac" action="include"/>
<prop att="platform" val="linux" action="exclude"/>
</val>
<val>
<prop att="platform" val="mac" action="exclude"/>
<prop att="platform" val="linux" action="include"/>
</val>
Because the title and metadata each contain filterable content, processing using the
conditions that are referenced by the <ditavalref>
element results in
two variants of the title and common metadata. While this cannot be expressed using valid
DITA markup, it is conceptually similar to something like the following.
<!-- The following wrapperElement is not a real DITA element.
It is used here purely as an example to illustrate one possible
way of picturing the conditions. -->
<wrapperElement>
<map>
<title>Setting up my product on <keyword platform="mac">Mac</keyword></title>
<topicmeta>
<othermeta platform="mac" name="ProductID" content="1234M"/>
</topicmeta>
<ditavalref href="mac.ditaval"/>
<!-- lots of content, including relationship tables -->
</map>
<map>
<title>Setting up my product on <keyword platform="linux">Linux</keyword></title>
<topicmeta>
<othermeta platform="linux" name="ProductID" content="1234L"/>
</topicmeta>
<ditavalref href="linux.ditaval"/>
<!-- lots of content, including relationship tables -->
</map>
</wrapperElement>
How this map is rendered is implementation dependent. If this root map is rendered as a PDF, possible renditions might include the following:
- Two PDFs, with one using the conditions from mac.ditaval and another using the conditions from linux.ditaval
- One PDF, with a title page that includes each filtered variant of the title and product ID, followed by Mac-specific and Linux-specific renderings of the content as chapters in the PDF
- One PDF, with the first set of filter conditions used to set book level titles and
metadata, followed by content filtered with those conditions, followed by content filtered
with conditions from the remaining
<ditavalref>
element.
Example: Multiple <ditavalref>
elements in a reference to a
map
This section is non-normative.
In this scenario, multiple instances of the <ditavalref>
element
are specified in a reference to a map. This is equivalent to referencing that map multiple
times, with each reference nesting one of the <ditavalref>
elements.
Example
This section is non-normative.
In the following example, other.ditamap is referenced by a root map.
The <ditavalref>
elements provide conflicting sets of filter
conditions.
<topicref href="parent.dita">
<topicref href="other.ditamap" format="ditamap">
<ditavalref href="audienceA.ditaval"/>
<ditavalref href="audienceB.ditaval"/>
<ditavalref href="audienceC.ditaval"/>
</topicref>
</topicref>
This markup is functionally equivalent to referencing other.ditamap
three times, with each reference including a single <ditavalref>
elements. The fragment could be rewritten as:
<topicref href="parent.dita">
<topicref href="other.ditamap" format="ditamap">
<ditavalref href="audienceA.ditaval"/>
</topicref>
<topicref href="other.ditamap" format="ditamap">
<ditavalref href="audienceB.ditaval"/>
</topicref>
<topicref href="other.ditamap" format="ditamap">
<ditavalref href="audienceC.ditaval"/>
</topicref>
</topicref>
Example: <ditavalref>
within a branch that already uses
<ditavalref>
This section is non-normative.
In this scenario, a branch is filtered because a <ditavalref>
element is present, and another <ditavalref>
deeper within that branch
supplies additional conditions for a subset of the branch.
Example
This section is non-normative.
<topicref href="install.dita">
<ditavalref href="linux.ditaval"/>
<ditavalref href="mac.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-mac</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<ditavalref href="win.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-win</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<topicref href="perform-install.dita">
<!-- other topics-->
</topicref>
<!-- Begin configuration sub-branch -->
<topicref href="configure.dita">
<ditavalref href="novice.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-novice</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<ditavalref href="advanced.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-admin</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<!-- Other config topics -->
</topicref>
<!-- End configuration sub-branch -->
</topicref>
In this case, the effective map contains three copies of the complete
branch. The branches are filtered by operating system. Because topics in the branch are
filtered in different ways, processors are effectively required to handle three copies of
the entire branch. The map author uses the <dvrResourceSuffix>
elements to control naming for each copy. The Linux branch does not specify a
<dvrResourceSuffix>
element, because it is the default copy of the
branch; this allows documents such as install.dita to retain their
original names.
Within each operating system instance, the configuration sub-branch
is repeated; it is filtered once for novice users and then again for advanced users. As a
result, there are actually six instances of the configuration sub-branch. Additional
<dvrResourceSuffix>
elements are used to control naming for each
instance.
- 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 the
<ditavalref>
the references novice.ditaval adds thesuffix -novice
. - 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. There is no renaming based on
linux.ditaval, and the
<ditavalref>
that references advanced.ditaval adds the suffix-admin
. - 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-novice-mac.dita. The
<ditavalref>
that references novice.ditaval adds the suffix-novice
, resulting in configure-novice.dita, and then the<ditavalref>
that references mac.ditaval adds the additional suffix-mac
. - 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-admin-mac.dita. The
<ditavalref>
that references admin.ditaval adds the suffix-admin
, resulting in configure-admin.dita, and then the<ditavalref>
that references mac.ditaval adds the additional suffix-mac
. - 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-novice-win.dita. The
<ditavalref>
that references novice.ditaval adds the suffix-novice
, resulting in configure-novice.dita, and then the<ditavalref>
that references win.ditaval adds the additional suffix-win
. - 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-admin-win.dita. The
<ditavalref>
that references admin.ditaval adds the suffix-admin
, resulting in configure-admin.dita, and then the<ditavalref>
that references win.ditaval adds the additional suffix-win
.
Example: <ditavalref>
error conditions
This section is non-normative.
In this scenario, multiple, non-equivalent copies of the same resource name are created as a result of branch filtering. In addition, the process results in duplicate key names, making it impossible to reliably reference individual result topics.
Example
This section is non-normative.
The following map fragment 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>
<dvrResourceSuffix>-token</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
<ditavalref href="two.ditaval">
<ditavalmeta>
<dvrResourceSuffix>-token</dvrResourceSuffix>
</ditavalmeta>
</ditavalref>
</topicref>
<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">
<!-- c-token.ditaval to be filtered by one.ditaval -->
</topicref>
<topicref href="c-token.dita" keys="c">
<!-- c-token.ditaval to be filtered by two.ditaval, key "c" ignored -->
</topicref>
- The key names "a" and "b" are present in a branch that will be duplicated. No key scope is introduced for either version of the branch, meaning that the keys will be duplicated. Because there can only be one effective key definition for "a" or "b", it only is possible to reference one version of the topic using keys.
- The key name "c" is present on another branch that will be duplicated, resulting in the same problem.
- The file c.dita is filtered with two sets of conditions, each of which explicitly maps the filtered resource to c-token.dita. This is an error condition that processors need to report.
- In situations where resource names map directly to output file names, such as an HTML5
rendering that creates files based on the original resource name, the following name
conflicts also occur. In this case a processor would need to report an error, use an
alternate naming scheme, or both:
- a.dita generates a.html using three alternate set of conditions. One version uses one.ditaval, one version uses two.ditaval, and the third version uses no filtering.
- b.dita generates b.html using two alternate set of conditions. One version uses one.ditaval, and the other version uses two.ditaval.