OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

dita message

[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]


Subject: [DITA 1.3/2.0] Keyref Not Sufficient for General Element-to-ElementAddress Indirection


I've been struggling ever since we started the DITA 1.2 discussion to
clearly articulate my indirect addressing requirements. At the time, I
proposed a general id-to-id indirection mechanism that provided a generic
indirection mechanism. That proposal was set aside in favor if keyref,
partly on the argument that keyref satisfied the indirection requirements. I
felt at the time that it did not but never could quite articulate the
details. 

I now can articulate them. The end of this message contains a potential
solution that I think may be appropriate for proposing in DITA 1.3.

But first an explanation of why I think a solution is needed at all:

The value of indirect addressing is that in the most general case it
provides the following benefits:

1. Protects references from changes in the *location* of the target (that
is, how things are named within a storage or addressing space, e.g., changes
to filenames of XML documents or IDs of element elements).

2. Protects references from changes in the *nature* of the target (that is,
how things are organized as structures or into storage objects, e.g.,
splitting one document into two, combining two documents into one, splitting
one element into two, or combining two elements into one).

Item (1) is about moving or renaming things without breaking references.
Without indirection, any change in the location of a target (including
creating a new version of it) necessarily requires updating *all pointers*
to the thing. Which requires creating new versions of all those things,
which in turn requires updating any pointers to those things, and so. So you
either use indirection or you impose draconian constraints on your ability
to move and rename things or you give up important functionality, like the
ability to explicitly point to older versions of documents.

By using indirection, you can have exactly one location-specific,
version-specific pointer to a thing and then use that as the target for all
other pointers to the thing. When the location of the thing changes, you
only update one pointer, not an unlimited number. The indirection itself has
an invariant address (meaning that pointers to the indirection object never
have to change).

Item 2 is about splitting or combining things without breaking references.
If a thing breaks into two, you update the original indirection object to
point to both things rather than one thing. Likewise, if two things are
combined into one, the indirections for each of the original things can now
point to the new combined object.

The keyref mechanism only provides benefit (1), it does not provide benefit
(2), as explained below. In addition, keyref only provides generalized
indirection for *topics*, not for elements within topics. However, having
the ability to simply move or rename things is tremendously valuable.

The keyref mechanism provides for indirect addressing of *topics* [ignoring
the use of keyref to address elements in <topicmeta>, which is useful but
not relevant to this discussion]. In particular, a reference to a given key
can be redirected to different topics in different map contexts without
modifying the original references to the key itself.

However, this is always a one-to-one indirection: there is no way to
redirect from a reference to a single key to multiple result topics (because
keyref= only takes a single value), which means you can't do something like:

<topicref key="one" keyref="two three"/>
<topicref key="two" href="thing-two.dita"/>
<topicref key="three" href="thing-three.dita"/>

You can map multiple things to a single result by specifying multiple keys
in a keys= attribute, but that has no practical effect in this discussion
because there's no way to have an initial reference to multiple targets.
(That is, you can create multiple aliases for single topic but you cannot
collapse a single reference to multiple topics to a single result topic.)

This is a limitation in that it does not allow for the case where a single
topic is subsequently split into two or more topics that, as a group, should
be the target of any references to the original topic, except by creating a
parent topic that contains both new topics.

This is probably not a severe limitation in practice but it is a limitation
nevertheless.

Note that, for topics, the keyref mechanism provides for name-remapping
because a key-defining topic can itself use keyref to point to another
key-defining topic. This allows you to change the primary name for a topic
without invalidating all existing references to the original name (assuming
you don't then reassign that name to some other topic).

So keyref completely provides value (1) for pointers to topics because you
can map key to both new storage locations (new href= values) and new names
(other keys). However, it does not completely provide value (1) for elements
and does not provide value (2) at all.

By "elements" I mean elements within topics that may be addressed directly.
This includes elements addressed by conref and xrefs, both of which may
address elements within topics.

Unfortunately, the keyref mechanism only partly provides value (1) for
elements.

This is because keyref only lets you specify a sub-topic element ID as part
of a keyref but does not allow key-defining topicrefs to remap the element
ID, only the key itself.

This means that you cannot change element IDs or split or combine elements
without breaking *all references* to those elements regardless of whether or
not you use keyref.

In fact, the use of keyref adds an addition requirement to coordinate the
IDs and structures used within otherwise unrelated topics so that references
to sub-topic elements will continue to resolve.

In the case of controlled localization of topics this is probably not a
problem in practice because localization typically does not allow structural
changes to topics.

But in the non-localization case, for example, providing a new topic as
"plug-in" that serves to override an existing topic in an existing body of
data, the creator of the plug-in topic must ensure that all the *potential*
reference target elements (that is, elements with IDs in the original) are
provided for in the plug-in topic. And this is not just at topic creation
time, but over the life span of both the original and plug-in topic because
the plug-in topic has to react to any changes to the original topic that add
or change element IDs that *might* be link targets.

This seems like a pretty severe limitation and a pretty onerous content
management/author coordination imposition, one that requires either
abandoning the use of element-to-element links except in very controlled
circumstances or the addition of expensive content management practices
and/or tools. It puts the details of information management back into topics
rather than containing it in maps where it belongs.

The solution would be to provide additional indirection mechanisms for
mapping element IDs to elements, in particular, to allow for renaming of
elements.

Thinking about it now, I think this could be done as a relatively simple
extension to the keyref framework that allows a key-defining topicref to
include a map from element IDs to target elements, e.g. Something like:

<topicref key="key-one" href="my-topic-one.dita">
  <topicmeta>
    <elementMap>
     <elementMapItem id="sect-01" target="s-234642q341"/>
     <elementMapItem id="sect-02" keyref="key-two/sect-02"/>
    </elementMap>
  </topicmeta>
</topicref>
<topicref key="key-two" href="my-topic-two.dita">
  <topicmeta>
    <elementMap>
     <elementMapItem id="sect-02" target="s-foo"/>
    </elementMap>
  </topicmeta>
</topicref>


Given the above and the keyref value "key-one/sect-01" the ultimate target
would be the element with the ID 's-234642q341" in the topic
"my-topic-one.dita". The keyref "key-one/sect-02" would resolve to the
element with the ID "s-foo" in the topic "my-topic-two.dita".

This would satisfy the renaming and moving requirement for elements while
still imposing the one-to-one mapping of source to target currently imposed
by keyref (which is consistent with general-one-to-one addressing and
linking constraints already imposed by DITA 1.x).

This design feels to me like a natural extension to the base keyref=
mechanism that doesn't require, as my original proposal did, a completely
separate mechanism for indirecting element ID references.

It would remove the need for topic authors to maintain an id-by-id match to
other topics that use the same key and move the address management work into
the map, where it belongs, rather into topics, which should not have to know
anything about other topics.

Cheers,

Eliot

----
Eliot Kimber | Senior Solutions Architect | Really Strategies, Inc.
email:  ekimber@reallysi.com <mailto:ekimber@reallysi.com>
office: 610.631.6770 | cell: 512.554.9368
2570 Boulevard of the Generals | Suite 213 | Audubon, PA 19403
www.reallysi.com <http://www.reallysi.com>  | http://blog.reallysi.com
<http://blog.reallysi.com> | www.rsuitecms.com <http://www.rsuitecms.com> 



[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]