DITA⇒よくわかりません(その4)

今回はkeyrefで参照先が「キー定義のtopicrefにあるXMLコンテンツへの参照」になる場合です.「コンテンツ参照」なので、対象が参照され参照元にコンテンツを持ってきてくれます.
 
今までkeydefでは必ず@hrefがあって、画像のURIやtopicを指していました.しかし中にはkeydefで@hrefがない定義も書けます.例えば2013年2月のDITAフェスタで紹介された例ですが、携帯電話のNokiaでは次のように書いているそうです.
 
[キー定義のマップ]
<map id="GUID-D723C387-4C20-43D4-84EA-878AD994C1FB" xml:lang="en">
  <topicgroup>
    <keydef keys="product_name" processing-role="resource-only">
      <topicmeta>
        <navtitle>product_name</navtitle>
        <keywords><keyword>Nokia Lumia 900</keyword></keywords>
      </topicmeta>
    </keydef>
    ...
  </topicgroup>
</map>
<map id="GUID-C14827DC-C7FC-48A7-91C2-1965CB961FC1" xml:lang="en">
  <topicgroup>
    <keydef keys="application_name" processing-role="resource-only">
      <topicmeta>
        <navtitle>application_name</navtitle>
        <keywords><keyword>Social</keyword></keywords>
      </topicmeta>
    </keydef>
    ...
  </topicgroup>
</map>
 
[キーの参照]
<shortdesc>If you feel like reaching out to your friends, use your <ph keyref="product_name"></ph> to let them know what's on your mind. Post your status to <uicontrol><keyword keyref="application_name"></keyref></uicontrol> app.</shortdesc>
 
これをXMetaLで開いてみた表示画面は以下のようになります.
 
イメージ 1
 
ご覧いただくわかるように、確かに<ph>と<keyword>要素のキー参照が、キー定義の<keydef>の下位に定義された最初の<keyword>の値が挿入されて表示されています.これをDITA-OTで処理すると、中間ファイルの<shortdesc>ではキー参照が置換されて次のようになっています.
 
<shortdesc class="- topic/shortdesc " xtrf="..." xtrc="shortdesc:1">If you feel like reaching out to your friends, use your <ph keyref="product_name" class="- topic/ph " xtrf="..." xtrc="ph:1">Nokia Lumia 900</ph> to let them know what's on your mind. Post your status to <uicontrol class="+ topic/ph ui-d/uicontrol " xtrf="..." xtrc="uicontrol:1"><keyword keyref="application_name" class="- topic/keyword " xtrf="..." xtrc="keyword:1">Social</keyword></uicontrol> app.   </shortdesc>
 
これからわかるように@hrefのないkeydefはいわば「変数」の定義みたいなものです.そして、keyrefはその「変数の参照」となります.このような変数は、文書中で製品名などを記述する際に大変便利です.ポイントはあくまで「変数」なのでテキストベースの内容しか格納できないという点でしょう.
 
このkeyrefの詳細な仕様は次で紹介されています.意外と難解です.
 
 
1.For elements on which no @href attribute is available (such as cite, dt, keyword, term, ph, indexterm, index-base, and indextermref, and their specializations), matching content is taken from the <keyword> or <term> elements within <keywords> within <topicmeta>. If more than one <keyword> or <term> is present, the matching content is taken from the first of them.
2.For elements that in addition to @keyref or @conkeyref do specify an @href attribute (such as author, data, data-about, image, link, lq, navref, publisher, source, topicref, xref, and their specializations), matching content includes all elements from within the key definition element that are in valid context within the key reference. Elements that are invalid within the key reference element directly or after generalization are not included or are filtered out.
 
何故このような仕様になっているか?なんて考え出すと大変です.WEBを探すとこのkeyrefに関しては様々な議論があったことがメーリングリストなどで残されています.これをトレースするのはちょっと無理かもです.
 
前回Eclipseでこの@keyrefがどう動くかデバッグしてみたのですが、この仕様のインプリメントはDITAのXSLTスタイルシートではなくJavaのコードの中にあります.ちょっと古いのですが、GitHubよりこちらのCVSの方が直接的で最新版よりわかりやすいです.228行のendElementメソッドで@keyrefが処理されています.興味のあるかたはご覧ください.
 
私には上記の2の「matching content includes all elements from within the key definition element that are in valid context within the key reference」というのは必ずしもインプリメントされていないように見えますがいかがでしょうか?「in valid context within the key reference」ではなく<keyword>と<term>だけしか「matching content」にならないからです.しかしこのコードはもうずっと変わっていないようです.
 
 
さてDITAの大御所Eliot KimberさんのDITA for Practitioners: Volume I を読むと、keyrefについてつぎのように書かれておられます.
 
1.keyrefによる参照を"variable"とクオートつきで表現しています.これはDITAのkeyrefはプログラミング言語の変数のようにスコープを持てないからです.DITA1.2ではkeyrefによって得られる値は文書全体でグローバルになります.文書のサブツリーでkeyrefの参照に別の値を割り当てる機能はありません.
 
2.もしキーが未定義だったときに割り当てるフォールバックテキストを定義することができません.たとえばfooという値を参照するkeyrefが見つからなかったとき"{variable foo not defined}"と表示したくともkeyはmapに定義されていて、そのような方法はありません.
 
これらの問題はすでにDITA1.3の仕様検討で議論されているようです.ともかく言えることはconkeyrefはconrefを間接参照に変えるものでした、一方keyrefはそれとは違った役割が求められて現在のような仕様になっています.conkeyrefは明確ですが、keyrefはその仕様にちょっと議論のあるところでしょう.しかし使えれば便利なことはいうまでもありません.DITA1.3でどのようにkeyrefが発展するか楽しみです.