以前topicのid属性はそのファイル内でユニークであれば良いということを書きました.それではDITAではtopic以外の要素のidはどうなっているのでしょうか?実はパーサーでは検証できない複雑な条件があります.
まずtopic以外の要素のid属性はDTDではIDではなくNMTOKENとして定義されています.もしDITA-OT 2.0以前のものをお持ちでしたら、[DITA-OT]\dtd\base\commonElements.modを見ていただくと次のようになっているのを確認できます.
<!ENTITY % id-atts
'id
NMTOKEN
#IMPLIED
%conref-atts;'
>
つまりパーサーではid属性の一意性は検証されません.しかしなんでもよいという訳ではありません.DITAの仕様では次のように書かれています.
2.1.3.4.1 ID attribute
Within documents containing multiple topics, the IDs for all non-topic elements that have the same nearest ancestor topic element should be unique with respect to each other. The IDs for non-topic elements may be the same as non-topic elements with different nearest ancestor topic elements.
ここで書かれていることは、id属性については次の図のような制約条件があるということになります.
次のtopicはこの条件を満たしています.直近の親のtopicが別ならid属性は重複してもかまわないのです.
[topic_conref.xml]
<topic id="topic_001">
<title>Topic title #1</title>
<body>
<p id="p_001">ABC</p>
<p id="p_002">DEF</p>
</body>
<topic id="topic_002">
<title>Topic title #2</title>
<body>
<p id="p_001">GHI</p>
<p id="p_002">JKL</p>
</body>
</topic>
</topic>
実際次のようにconrefしてみるとoXygenでちゃんと表示されます.
<topic id="topic_jng_xxn_w4">
<title>Conref sample</title>
<body>
<p>Paragraph samples that referes to topic_conref.xml</p>
<p conref="topic_conref.xml#topic_001/p_001"/>
<p conref="topic_conref.xml#topic_001/p_002"/>
<p conref="topic_conref.xml#topic_002/p_001"/>
<p conref="topic_conref.xml#topic_002/p_002"/>
</body>
</topic>
これを検出するコードがどこにあるのか調べてみましたが、たぶん次です.これはoXygenのインストールフォルダのframeworks\dita\resources\dita-1.2-for-xslt2-mandatory.schの以下の部分です.
<!--EXM-21448 Report duplicate IDs start pattern-->
<xsl:key name="elementsByID" match="*[@id][not(contains(@class, ' topic/topic '))]"
use="concat(@id, '#', ancestor::*[contains(@class, ' topic/topic ')][1]/@id)"/>
<pattern id="checkIDs">
<rule context="*[@id]">
<let name="k" value="concat(@id, '#', ancestor::*[contains(@class, ' topic/topic ')][1]/@id)"/>
<let name="countKey" value="count(key('elementsByID', $k))"/>
<report test="$countKey > 1" see="http://docs.oasis-open.org/dita/v1.1/OS/archspec/id.html">
</report>
</rule>
</pattern>
<!--EXM-21448 Report duplicate IDs end pattern-->
① [要素のid属性の値]+"#"+[直近の親のtopicのid属性の値]でキーを作る.
② このキーにマッチする要素数が2以上であればidがユニークでない旨のエラーメッセージを出す.
ちなみにこのスキーマトロンの作者はDITA-OTの開発者である、Jarno Elovirtaさんのものによります.
ところがXMetaLでは最初のtopic_conref.xmlはidが重複しているというエラーが報告されます.これはTools - Run Cross-file OperationでDetect duplicate idsを選択するとこうなってしまいます.
一般にはidはXMLエディタに自動生成させている限りこのような問題に遭遇することはありません.しかしDITAの大本の仕様としては理解していて損はないと思います.またXMLエディタの機能から言えば、この重複したidの検出はXMetaLではなくoXygenの方に軍配があがるようですね.