ある日スタイルシートをお客様からもらったデータで動かしていました.うまくXSL-FOが出来てFormatterのステップに行ってくれたのですが、やたらエラーメッセージが表示され組版が時間がかかります.なんとか終了したのですがid重複のエラーが3000行も出ていました.ギャッ!これでは遅くなるはずです.スタイルシートを修正してテストするのに、これでは毎回手間がかかってしょうがありません.
[XMetaLの場合:topicに自動的にユニークなid属性がつきます]
[oXygenの場合:topicに自動的にユニークなid属性がつきます]
両方ともエディタの機能を使ったときです.つまりXMetaLだと要素リストからtopicを選んで挿入します.oXygenだとオーサリングモードの表示にしてDITA-Insert-Insert Topicを選択します.XMLを直接編集するモードでは使えません.
問題はここからで、いったん作成したtopicを他で少し内容を変えて使いたいと言う場合、思わずファイル(File)-名前をつけて保存(Save As)、とやってしまうパターンが多いのではないかと思います.こうするとidが同じtopicができてしまいます.使っているCMSによっては、最上位のtopic/@idを自動的にユニークにしてくれる場合もあるようです.でもさすがに入れ子のtopicのidまでは面倒を見てくれません.
DITAではmapでtopicを結合したときに、topic/@idはユニークでなければならないのですが、実はDITA Open Toolkitはそこをうまく面倒を見てくれています.このidを使用せず自動的に中間ファイル上では"uniqueN"というidに置き換えてくれます.
これは良い面と悪い面があります.良い面は、CMSベースでやっていなような場合、上記のようにFile-Save Asをやって別のtopicを作ってしまう場合が多々あるのです.こういう事態であってもDITA Open Toolkitに任せておけばidの重複エラーを避けることができます.悪い面は、あるtopicにどのようなidがつけられるかはDITA-OTにお任せなので外からは値がわからない点です.たとえば複数のマニュアルのPDFを作って、互いに相手のPDFをリンクで参照したいという場合があります.このようなとき、DITA-OTが勝手につけたUniqueNのidでは参照しようがないのです.こういう時はもともと付いていたidを尊重してPDFの外に参照先としてexportしてやる必要があります.
⇒この方法についてはdita-usersでのEliot Kimberさんの質問を参照: http://tech.groups.yahoo.com/group/dita-users/message/31255
<!ENTITY % id-atts
'id
NMTOKEN
#IMPLIED
%conref-atts;'
>
となっていて、
<!ENTITY % id-atts
'id
ID
#IMPLIED
%conref-atts;'
>
ではないのです.ですので検証では重複はチェックされません.このようなid属性がエディタでどうなるのでしょうか?ol/liの場合についてみてみました.ol/liはxrefの参照先にもなりえるのでidが重要だからです.
[XMetalはol/liにちゃんとidを振ってくれます.]
[oXygenはolにはidを振りますが、ol/liにはidを振ってくれません.]
この機能の違いもあってか、XMetaLで人為的にol/liに同じidを入れてみてもなんのエラーにもなりません.これはもともとDTDで重複を検出することができないので無理もありません.
[XMetaLで重複したol/liのidを入れて検証]
oXygenは自動的にidをol/liに振ってくれませんが、人為的にol/liに同じidを入れてみると、Shematronでエラーになります.
[oXygenで重複したol/liを入れて検証]
これはなかなか賢いです.DTDでは検出しようもないエラーをスキーマトロンは検出してくれます.ちなみにidはそれが属しているtopicでユニークであれば良いのですが、入れ子のtopicでそれぞれ同じidのol/liを入れてもエラーにはなりません.やはりXPathの威力は絶大です.
このあとではスタイルシートでidの重複を防ぐにはどうしたら良いか少し考えてみたいと思います.