XMLベースのDarwin Information Typing Architecture (DITA) の目的は、モジュール化された技術文書を作成することです。この文書は、ヘルプセット、マニュアル、および小画面デバイス用の階層化された要約などの、さまざまな表示および送達機構で容易に再使用できます。この記事では、DITAの原理を実現する方法について説明します。
特殊化は、作成者や設計者が、既存のスタイル・シート、トランスフォーム、およびプロセスとの互換性を維持しつつ、新しいトピック・タイプを定義するために使用するプロセスです。新しいトピック・タイプは、既存のトピック・タイプを基準とした拡張部分 (またはデルタ) として定義されるので、新しいタイプの定義と保守に必要な作業は少なくてすみます。
この記事の例ではXML DTD構文とXSLTが使用されています。これらについての背景情報が必要な場合は、 参考文献 を参照してください。
SGMLにおいて、アーキテクチャー・フォームは、1つの文書タイプから別の文書タイプへのマッピングを提供する古典的な方法です。特殊化は、より限定された問題に対する、アーキテクチャー・フォームに似たソリューションであり、より限定的なトピック・タイプから、より一般的なトピック・タイプへのマッピングを提供します。限定的なトピック・タイプは一般的なトピック・タイプを念頭に置いて開発されているため、特殊化では、アーキテクチャー・フォームが扱っている難しい問題の多くを無視できます。このように領域が限定されているために、特殊化プロセスは比較的容易にインプリメントして保守できます。特殊化では、マルチレベルまたは階層型の特殊化もサポートされており、より一般的なトピック・タイプをさまざまな特殊化されたタイプの公分母として使用できます。
アーキテクチャー・フォームを使用すれば、等価の構造を持つ複数の文書タイプの間を行き来することができます。特殊化を使用すれば、特殊化された文書タイプからより一般的な文書タイプに、一方向のトランスフォームを行えます。アーキテクチャー・フォームでは、関係する文書タイプで等価の構造がサポートされていることが想定されていますが、特殊化では、1つのトピック・タイプで他のトピック・タイプの構造のサブセットがサポートされていることが想定されています。
特殊化プロセスはDITAを処理するために作成されましたが、その原理とプロセスは他の領域にも適用されます。次のような例を考慮すると、これは大きな意味を持ちます。特殊化とHTMLなどの汎用のDTDがあれば、新しい文書タイプ (ここでは、MyHTMLとします) を作成できます。MyHTMLでは、企業のサイト標準を実施し、フォーム・レイアウト、見出しレベル、およびフォントや明滅タグの使用などに関する特殊な規則を含めることができます。さらに、製品および注文情報用に使用できるより限定的な構造を提供して、検索エンジンや他のアプリケーションでデータをより効果的に使用できるようにすることができます。
DITAを使用すれば、MyHTMLをHTML DTDの拡張部分として定義し、必要な場合にのみ新しいエレメント・タイプを宣言したり、共用エレメント用にHTMLのDTDを参照したりできます。MyHTMLで宣言される新しいエレメントには、既存のHTMLエレメントに戻るマッピングが含まれます。このマッピングにより、MyHTML文書に対しても同様に機能する、HTML用のスタイル・シートやトランスフォームの作成が可能となります。構造を別の仕方で処理する (たとえば、製品情報を特定の仕方で形式設定する) には、拡張動作を保持する新しいスタイル・シートまたはトランスフォームを定義してから、残りの動作を処理する標準のスタイル・シートまたはトランスフォームをインポートできます。言い換えると、新しい動作は、新しい制約が元のDTDやスキーマに拡張機能として追加されるのと同じように、元のスタイル・シートに拡張部分として追加されます。
Darwin Information Typing Architectureでは、情報タイプと同じほど文書タイプは考慮されていません。文書は、それぞれが独自の情報タイプを持ついくつかのトピックで構成されていると見なされます。トピックは、見出しとテキストで構成される (オプションでセクションに分割された) 情報のチャンクにすぎません。情報タイプはトピックのコンテンツを記述します。たとえば、特定のトピックのタイプは "概念" または "タスク" です。
DITAには3つのタイプのトピック (汎用トピック (または、情報タイプの付いた概念)、タスク、および参照トピック) です。概念、タスク、および参照トピック (reftopic) はすべて、トピックを特殊化したものと見なせます。
図1. トピックを特殊化したものである3つの情報タイプ
付加的な情報タイプは、これらの3つの基本的なタイプのいずれかを特殊化したものとしてアーキテクチャーに追加できます。その情報タイプをさらに特殊化することもできます。
図2. 拡張され、より特殊化されたタイプが組み込まれたアーキテクチャー
それぞれの新しい情報タイプは、既存の情報タイプの拡張部分として定義されます。特殊化タイプは、すべての共通構造を重複なしに継承します。さらに、自身の新規エレメントと一般タイプの既存エレメントとの間のマッピングを提供します。それぞれの情報タイプは独自のDTDモジュールで定義されます。ここでは、そのタイプで使用される新しいエレメントだけが定義されます。1つの情報タイプだけで構成される文書 (たとえば、ヘルプWebのタスク文書) の場合、文書タイプは情報タイプの特殊化階層に存在するすべてのモジュールで定義されます。複数の情報タイプを持つ文書タイプ (たとえば、概念、タスク、およびreftopicで構成されるブック) には、使用されるそれぞれの情報タイプに対応するモジュールと、上位タイプに対応するモジュールが含まれます。
情報タイプ宣言はモジュールに分割されているため、上位タイプに影響を及ぼさずに新しい情報タイプを定義できます。この分割には、次のような利点があります。
- 保守コストが削減される: 各オーサリング・グループは、独自に必要とするエレメントだけを保守する
- 互換性が向上する: コア情報タイプを集中保守でき、コア・タイプへの変更内容はすべての特殊化タイプで反映される
- 制御が分散される: 再使用可能性は、作成者でなく再使用者によって制御される。新しいタイプを追加しても、コア・タイプの保守は影響を受けず、別のタイプの他のユーザーも影響を受けない
情報タイプの付いたトピックはすべて、複数のタイプに属します。たとえば、API記述は、より一般的な用語で言うと、参照トピックです。
次のような参照トピックの特殊化階層について考慮してみましょう。
図3. 単純な特殊化階層
表1は、
topic
にある一般エレメントと
reftopic
にある特殊エレメントの関係を表しています。表の列、行、セルはそれぞれ、情報タイプ、エレメント・マッピング、およびエレメントを示しています。表2は、表1を理解するのに役立つよう、関係を詳細に説明しています。
表1. トピックと、トピックに基づく特殊化の関係
| トピック | reftopic |
|---|---|
| (topic.mod) | (reftopic.mod) |
| topic | reftopic |
| title | |
| body | refbody |
| dl | properties |
| section | synsect |
| refsect |
表2. 表1の説明
| 構造 | 関連 |
|---|---|
| 列 |
トピック列は、基本的な
topic
の構造を示しています。これは、オプションのセクションである表題 (title) と本文
(body) で構成されており、
topic.mod
という名前のDTDモジュールで宣言されています。reftopic
列は、より特殊化された構造を示しています。
reftopic
によって
topic
が置き換えられ、
refbody
によって
body
が置き換えられ、
synsect
と
refsect
によって
section
が置き換えられています。これらの新しいエレメントは、
reftopic.mod
という名前のDTDモジュールで宣言されています。
|
| 行 |
各行は、その行にあるエレメントの間のマッピングを表しています。reftopic
列にあるエレメントは、トピック列にあるエレメントを特殊化したものです。それぞれの一般エレメントは、同じ行にあるより特殊化されたエレメントのカテゴリーも示しています。たとえば、
reftopic
にある
synsect
は
section
の一種です。
|
| セル |
列にある各セルは、左側にあるセルとの関係について、次のものを表しています。
|
リスト1は、
reftopic.mod
の実際の内容ではなく、表1に基づく単純化されたバージョンを示しています。
リスト1. reftopic.mod
<!ELEMENT reftopic (title, prolog?, refbody,(%info-types;)* )>
<!ELEMENT refbody ((refsect | refsyn|properties)*)>
<!ELEMENT properties ((dthd,ddhd?)|ddhd)?, (dlentry)+) >
<!ELEMENT refsect (%section;)* >
<!ATTLIST refsect label CDATA #IMPLIED>
<!ELEMENT refsyn (%section;)* >
<!ATTLIST refsyn label CDATA #IMPLIED>
|
ここで宣言されているほとんどのコンテンツ・モデルは、
topic.mod
で宣言されているエレメントやエンティティーに依存しています。したがって、
topic
の構造が拡張または変更されると、ほとんどの変更内容は
reftopic
で自動的に採用されます。また、
reftopic
の定義は単純なままです。
topic
と共用しているコンテンツを再宣言する必要はありません。
ここでは、エレメントのマッピングを公開するため、より一般的なタイプへのマッピングを示す属性を各エレメントに追加します。
リスト2. reftopic.mod (第2部)
リスト2. reftopic.mod (第2部)
<!ATTLIST reftopic spec CDATA "topic reftopic">
<!ATTLIST refbody spec CDATA "topic.body reftopic.refbody">
<!ATTLIST properties spec CDATA "topic.dl reftopic.properties">
<!ATTLIST synsect spec CDATA "topic.section reftopic.synsect">
<!ATTLIST refsect spec CDATA "topic.section reftopic.refsect">
|
後で、XSLトランスフォームの作成時にこれらの属性を利用する方法について説明します。
タイプ・モジュール (新しくタイプ指定されたエレメントとその属性を宣言する) を定義し、特殊化属性 (新しいタイプをその上位タイプにマップする) を追加したら、オーサリングDTDをアセンブルできます。
リスト3. reftopic.dtd
<!--Redefine the infotype entity to exclude other topic types-->
<!ENTITY % info-types "reftopic">
<!--Embed topic to get generic elements -->
<!ENTITY % topic SYSTEM "topic.mod">
%topic;
<!--Embed reftopic to get specific elements -->
<!ENTITY % reftopic SYSTEM "reftopic.mod">
%reftopic;
|
次に、より特殊化された情報タイプであるAPI記述を作成しましょう。これは、参照トピックの一種 (したがって、参照トピックを特殊化したもの) です。
図4. より特殊化された情報タイプ、API記述
表3は、API記述を表すAPIdesc という名前の情報タイプの特殊化の一部を示しています。前と同じように、各列は情報タイプを表し、左から右の方向に特殊化が行われています。つまり、各情報タイプは、左にあるものを特殊化したものです。各行はマップされた一連のエレメントを表し、右にあるより限定的なエレメントが、左にあるより一般的なエレメントにマップされています。
前の例と同じように、各セルでは、左にあるセルの内容が特殊化されています。
-
ブランク・セル: 左にあるエレメントがそのまま新しいタイプで採用されます。たとえば、
dlとsynsectはAPI記述でも使用可能です。 -
同サイズのセル: 左にあるエレメントがより限定的なエレメントで置き換えられます。たとえば、
titleはAPInameで置き換えられます。 -
ブランク・セルを含む分割行:
左にあるエレメントに新しいエレメントが追加されます。たとえば、API記述では、
usageセクションがsynsectおよびrefsectエレメントと対等のエレメントとして追加されます。
表3. APIdesc特殊化の要約
| トピック | reftopic | APIdesc |
|---|---|---|
| (topic.mod) | (reftopic.mod) | (APIdesc.mod) |
| topic | reftopic | APIdesc |
| title | APIname | |
| body | refbody | APIbody |
| dl | properties | parameters |
| section | synsect | |
| refsect | ||
| usage |
ここでは、API記述のコンテンツが実際に一般的な参照トピックのコンテンツよりもずっと限定されていることが分かります。構文、使用法、パラメーターの順序が強制され、オプションで付加的なセクションが続きます。この順序は、参照トピックで許可される構造
(構文、プロパティー、およびセクションを任意の順序で並べることができる) のサブセットです。さらに、usage
section
のラベルが、
refsect
のラベルのようにオプションまたは作成者定義である代わりに、
Usage
に修正されています。
リスト4. APIdesc.mod
<!ELEMENT APIdesc (APIname, prolog?, APIbody,(%info-types;)* )>
<!ELEMENT APIname ((%title.cnt;)*)>
<!ELEMENT APIbody (refsyn,usage,parameters,refsect*)>
<!ELEMENT usage (%section;)* >
<!ATTLIST usage label CDATA #FIXED "Usage">
<!ELEMENT parameters ((dthd,ddhd?)|ddhd)?,(dlentry)+) >
|
すべての新しいエレメントには、上位エレメントへのマッピングが存在します。
APIname
については、reftopicとトピックとで対応するものが同じ (title)
であるにもかかわらず、明示的に識別されていることに注意してください。この識別のおかげで、プロセスで完全なマッピングを追跡しやすくなっています。特殊化階層が10レベル以上の深さであったとしても、これらの属性により、それぞれの上位情報タイプへの明確なマッピングが依然として可能です。
リスト5. APIdesc.mod (第2部)
<!ATTLIST APIdesc spec CDATA "topic reftopic APIdesc">
<!ATTLIST APIname spec CDATA "topic.title reftopic.title APIdesc.APIname">
<!ATTLIST APIbody spec CDATA "topic.body reftopic.refbody APIdesc.APIbody">
<!ATTLIST parameters spec CDATA "topic.dl reftopic.properties APIdesc.parameters">
<!ATTLIST usage spec CDATA "topic.section reftopic.refsect APIdesc.usage">
|
タイプ・モジュール (新しくタイプ指定されたエレメントとその属性を宣言する) を定義し、特殊化属性 (新しいタイプをその上位タイプにマップする) を追加したら、オーサリングDTDをアセンブルできます。
リスト6. APIdesc.dtd
<!--Redefine the infotype entity to exclude other topic types-->
<!ENTITY % info-types "APIdesc"><!--Embed topic to get generic elements -->
<!ENTITY % topic SYSTEM "topic.mod">
%topic;
<!--Embed reftopic to get more specific elements -->
<!ENTITY % reftopic SYSTEM "reftopic.mod">
%reftopic;
<!--Embed APIdesc to get most specific elements -->
<!ENTITY % APIdesc SYSTEM "APIdesc.mod">
%APIdesc;
|
特殊化されたタイプを定義し、必要な属性を宣言したら、以下の操作を行う基盤が得られたことになります。
- 一般的なスタイル・シートやトランスフォームを特殊化されたトピック・タイプに適用する
- 特殊化されたタイプのトピックを一般化する (より一般的なトピック・タイプに変換する)
- 一般的なタイプのトピックを特殊化する (より限定的なトピック・タイプに変換する。このトピック・タイプは、トピックがもともと特殊化されたフォームで作成され、元のフォームの制約に違反せずに一般的な段階を通過した場合にのみ使用できる)
新しい情報タイプ (たとえばAPIdesc) で作成されたコンテンツは、それ以前に存在していた情報タイプ (
たとえば
reftopic
)
にある等価または制約の少ない構造へのマッピングを持っているので、既存のトランスフォームやプロセスをその新しいコンテンツに安全に適用できます。デフォルトでは、新しい情報タイプにある特殊化されたエレメントはそれぞれ、一般的な等価のエレメントのインスタンスとして扱われます。たとえば、
APIdesc
では、
<usage>
エレメントは、トピックの
<section>
エレメントにたまたま固定ラベル
"Usage"
が付いたものとして扱われます。
作成者がこのデフォルト動作をオーバーライドするには、単にそのエレメント・タイプに関するより限定的な規則を新しく作成してから、デフォルトのスタイル・シートやトランスフォームをインポートするだけで、元のスタイル・シートやトランスフォームを直接編集せずに動作を拡張できます。この参照による再使用により、保守コストは減少し (各サイトでは独自に必要な規則だけを保守する)、整合性は向上します (コアとなるトランスフォーム規則を集中保守でき、コア規則への変更内容が、それをインポートする他のすべてのトランスフォームで反映されるため)。再使用に対する制御権は、トランスフォームの作成者からトランスフォームの再使用者に移動します。
このセクションの残りの部分では、読者がXSLT (XSL Transformations) 言語の知識を持っていることを想定しています。
このプロセスが機能するのは、一般的なトランスフォームが特殊化されたエレメントを処理できるようになっていて、特殊化されたエレメントに、一般的なトランスフォームが処理するのに十分な情報が含まれている場合だけです。
要件1: マッピング属性
特殊化情報を提供するには、前に示したように特殊化属性を追加しなければなりません。この属性を文書に含めた後は、特殊化に対応したトランスフォームでその文書を処理できます。
要件2: 特殊化に対応したトランスフォーム
トランスフォームには、エレメント名と属性値に対する一致を検査するテンプレート規則が必要です。
この検査は2つの方法のいずれかによって実現できます。リスト7で示されているように、両方の場合マッチする単一のトランスフォーム規則を作成できます。
リスト7. 結合されたインターフェース
<xsl:template match="dl|*[contains(@spec,"topic.dl"]">
<!--matches either a dl, or any element that has a spec attribute
that mentions topic.dl -->
<!--do something-->
<xsl:apply-templates/>
</xsl:template>
|
あるいは、マッチがテンプレートの一致ステートメント (ループや条件ステートメントの中ではない) でのみ行われ、すべての処理が再帰的に行われるように、トランスフォームを作成することができます。その後で、テンプレートに名前を付け、特殊化を扱うインターフェース全体を並列に作成できます。
リスト8. 基本インターフェース
<xsl:template match="dl" name="topic.dl">
<!--matches a dl, or can be called by name-->
<!--do something-->
<xsl:apply-templates>
</xsl:template
|
リスト9. 特殊化に対応したインターフェース
<xsl:template match="*[contains(@spec,"topic.dl"]">
<!--matches any element that has a spec attribute that mentions
topic.dl, then calls the dl template by name-->
<!--do something-->
<xsl:call-template name="topic.dl">
</xsl:template>
|
特定エレメント用に一般的なトランスフォームをオーバーライドする場合、新しい情報タイプの作成者は、その特定エレメントについては新しい動作を宣言し、他のエレメントについては一般的なトランスフォームをインポートすることによってデフォルトの動作を提供する、トランスフォームを作成できます。
たとえば、
APIdesc
の特殊化されたトランスフォームでは、
parameters
を除くすべての特殊化されたエレメントをデフォルトの方法で処理できます。
リスト10. APIdescの特殊化されたトランスフォーム
リスト10. APIdescの特殊化されたトランスフォーム
<xsl:import href="general-transform.xsl"/>
<xsl:template match="parameters|*[contains(@spec,"APIdesc.parameters"]">
<!--do something-->
<xsl:apply-templates/>
</xsl:template>
|
parameters
エレメントが存在するときには、既存の
reftopic
properties
テンプレート規則と新しい
parameters
テンプレート規則の両方がマッチします (
parameters
エレメントは特殊化されたタイプの
reftopic
properties
エレメントであるため)。ただし、インポート元のスタイル・シートに
parameters
テンプレートがあるため、この新しいテンプレートが優先されます。
特殊化された情報タイプはその上位タイプのインスタンスでもあるため (APIdescはreftopicであり、トピックでもある)、特殊化されたトピックをより一般的な上位タイプに安全に変換できます。この上向き互換性が役立つのは、2つのソースから取得した (それぞれが異なる仕方で特殊化された) 一連の文書を結合するときです。上位タイプは、両方を安全に変換できる公分母となります。また、この互換性は、特殊化に対応していないプロセスでトピックを処理しなければならないときにも役立ちます (たとえば、DTDに対応していないソフトウェアを使用する翻訳センターでは、1つの文書タイプだけをサポートしたいかもしれません)。
トピックを安全に一般化するには、情報タイプをターゲット情報タイプにマップする手段が必要です。また、後で元に戻さなければならない場合は、元のタイプを保存しておく手段も必要です。
前に紹介した
spec
属性は、2つの目的を果たします。これは、次のものを提供します。
- マップするのに必要な情報
- 元に戻すことを可能にするための情報を保存する手段
各レベルの特殊化には独自のセットのspec属性があります。これにより、特殊化されたエレメントすべての完全な特殊化階層が最終的に実現します。
リスト11の
APIdesc
トピックを考慮してみてください。
リスト11. APIdescのサンプル・トピック
<APIdesc>
<APIname>AnAPI</APIname>
<APIbody>
<synsection>AnAPI (parm1, parm2)</synsection>
<usage label="Usage">Use AnAPI to pass parameters to your process.
</usage>
<parameters >
...
</parameters>
</APIbody>
</APIdesc>
|
spec
属性を公開する (DTDによってすべての値をデフォルトとして提供する) と、次のようになります。
リスト12. spec属性を含む、APIdescの同じサンプル・トピック
<APIdesc spec="topic reftopic APIdesc">
<APIname spec="topic.title reftopic.title APIdesc.APIname">AnAPI
</APIname>
<APIbody spec="topic.body reftopic.refbody APIdesc.APIbody">
<synsect spec="topic.section reftopic.synsection">AnAPI(parm1,
parm2)</synsection>
<usage spec="topic.section reftopic.section APIdesc.usage"
label="Usage">
<p>Use AnAPI to pass parameters to your process.</p>
</usage>
<parameters spec="topic.dl reftopic.properties APIdesc.parameters" >
...
</parameters>
</APIbody>
</APIdesc>
|
ここからは、単純なテンプレート規則により、
APIdesc
トピックを
reftopic
または一般トピックに変換できます。このテンプレート規則は、単に
spec
属性で上位エレメント名を探し、現在のエレメントの名前をそれと一致するように変更します。
spec
属性が存在しない場合 (たとえば
<p>
)、このテンプレート規則はエレメントをそのままにしておきます。
トピックに変換した後、コードはリスト13のようになります。
リスト13. APIdescから変換されたトピック
<topic spec="topic reftopic APIdesc">
<title spec="topic.title reftopic.title APIdesc.APIname">AnAPI
</title>
<body spec="topic.body reftopic.refbody APIdesc.APIbody">
<section spec="topic.section reftopic.synsect">AnAPI(parm1,
parm2)</section>
<section spec="topic.section reftopic.refsect APIdesc.usage"
label="Usage">
<p>Use AnAPI to pass parameters to your process.</p>
</section>
<dl spec="topic.dl reftopic.properties APIdesc.parameters" >
....
</dl>
</body>
</topic>
|
一般化の後でも、特殊化に対応したトランスフォームは、
spec
属性でエレメント名階層に関する情報を参照できるため、引き続きトピックを
APIdesc
として扱えます。
ここからは、変換を逆転させる (
spec
属性で特殊化元のエレメント名を参照してから、現在エレメントの名前をそれに合わせて変更する)
ことにより、元に戻すことが可能です。
spec
属性が存在しない場合 (
<p>
)、エレメントはそのままです。
spec
属性でターゲットがリストされていない (最初の
section
に
APIdesc
値がない) 場合、エレメントはリストされている最後の値に変更されます (したがって、最初の
section
は、正確に
synsect
になります)。
ただし、一般の
topic
である間にコンテンツの構造を変更する (たとえば、セクションの順序を変更する)
と、特殊化された情報タイプにおける結果は無効になる可能性があります (
APIdesc
の場合、
APIbody
の情報で特定の順序が強制されます)。したがって、より一般的なタイプへのマッピングは常に安全ですが、特殊化されたタイプに戻すマッピングは問題を引き起こす可能性があります。特殊化されたタイプの方が規則が多く、それによってコンテンツが特殊化されているためです。ただし、これらの規則は、コンテンツがより一般的にエンコードされている間は実施されません。
一般的なトピックの特殊化は、コンテンツがもともと特殊化されたタイプで作成されていれば、比較的単純です。しかしながら、一般的なレベルで作成したコンテンツをより正確にタイプ指定したい場合は、複雑になる可能性があります。
たとえば、一連の参照トピックを作成したとします。その後、コンテンツを分析して、一貫性のあるパターンの存在に気付きました。そこで、このパターンを強制し、特殊化された情報タイプ (たとえばAPI記述) によって記述するとします。特殊化を行うため、まずターゲットDTDを作成してから、マイグレーションするのに十分な情報をコンテンツに追加する必要があります。
特殊化元の情報は、次の2つの場所のいずれかに入れることができます。
-
spec属性に追加する。注意して、順序を正しく取得し、すべての上位タイプの値を含める必要があります。 -
ターゲット・エレメントの名前を
classif属性で指定し、その値に基づいてマイグレーションしてから、spec属性の値を後で追加します。
いずれの場合でも、マイグレーションの前に、適切な属性を探してエレメントの内容が特殊化されたコンテンツ・モデルの下で有効であることをチェックする、妥当性検査トランスフォームを実行できます。Schematronなどのツールを使用して、妥当性検査トランスフォームとマイグレーション・トランスフォームの両方を生成するか、まずマイグレーションしてから、特殊化されたDTDを使用してそのマイグレーションが正しく行われたことを検証することができます。
XML DTD構文と同様、XML Schema言語はボキャブラリー (エレメントと属性) やそのボキャブラリーに対する一連の制約 (コンテンツ・モデルや、固定属性または暗黙属性など) を定義する手段です。これには、許可される特殊化を制限する機能を含む特殊化機構が組み込まれています。DTDの代わりにXML Schema言語を使用すると、特殊化された情報タイプが一般タイプの有効なサブセットを表していることを検証するのが容易になります。これにより、汎用の変換およびパブリッシング・トランスフォームによるスムーズな処理が保証されます。
DTDとは異なり、XMLスキーマはXML文書として表されます。その結果、DTDでは行えないような仕方で処理できます。たとえば、単一のXMLスキーマを保守している場合、XSLを使用すれば、次の2つのバージョンを生成できます。
- 固定属性とオーバーライドされたエレメントがすべて除去された、オーサリング・バージョン
- 変換およびパブリッシング・トランスフォームを駆動するspec属性が含まれた、プロセッサー対応バージョン
ただし、XMLスキーマは、まだ心から受け入れることができるほど一般的ではありません。主な問題は、オーサリング・ツールが欠けていることと、規格の進化によるさまざまなインプリメンテーション間の非互換性です。これらの問題は、規格が完成に近づき、スキーマがより広く受け入れられてサポートされるとともに、来年のうちにも業界で解決されるはずです(訳注:XML Schemaは2001年5月に勧告となりました)。
特殊化された情報タイプは、次の一般的な手順で作成できます。
- 必要なエレメントを識別する。
- より一般的なタイプのエレメントへのマッピングを識別する。
- 特殊化されたエレメントのコンテンツ・モデルが、一般的なエレメントのコンテンツ・モデルよりも限定的であることを検証する。
-
特殊化されたエレメントおよび属性宣言 (
spec属性を含む) を保持するタイプ・モジュール・ファイルを作成する。 - 適切なタイプ・モジュールをインポートするオーサリングDTDファイルを作成する。
特殊化されたXSLトランスフォームは、次の一般的な手順で作成できます。
- 情報タイプ用の新しいトランスフォームを作成する。
- 拡張したい既存のトランスフォームをインポートする。
- 特殊な仕方で扱うことが必要なエレメントを識別する。
-
これらのエレメントに一致する (エレメント名と
spec属性の内容の両方によって) テンプレート規則を追加する。
一般的なDTDにあるどのタグについても、対応するものを新しいエレメントで作成できますが、そのタグを含むコンテンツ・モデルも特殊化するのでないかぎり、この作業は作成者にとって無意味です。
APIdesc
の例で、
parameters
エレメントは、
topic
または
reftopic
のどこにおいても、有効なコンテンツではありません。これを使用するには、トピック・レベルのコンテナーに至る、parameters用の有効なコンテキストを作成しなければなりません。
parameters
エレメントを作成者に公開するには、次の部分を特殊化しなければなりません。
-
parametersを有効なコンテンツとして許可するため、
bodyエレメント (APIbodyを作成する) -
特殊化されたbodyを許可するため、
topicエレメント (APIdescを作成する)
このドミノ効果は、スキーマに移行するとなくなります。スキーマでは、特殊化されたエレメントが認識され、対応する一般的なエレメントが許可されているかぎり許可されるからです。ただし、現在のところ、すべてを特殊化するには、トピック・レベルまで特殊化を行う必要があります。
特殊化されたエレメントが一般的なエレメントより限定的である (つまり、一般的なエレメントで許可される構造の適切なサブセットが許可される) ことを保証するには、一般的なエレメントのコンテンツ・モデルを参照する必要があります。特殊化されたエレメントのコンテンツ・モデルは、表Aのように安全に変更できます。
表A. 特殊化に関する規則の要約
| コンテンツ・ タイプ | 許可される特殊化 | 例 (SpecialはGeneralを特殊化したもの) |
|---|---|---|
| 必須 | 名前変更のみ | <!ELEMENT General(a)> <!ELEMENT Special(a.1)> |
| オプション (?) | 名前変更、必須への変更、削除 | <!ELEMENT General(a?)> <!ELEMENT Special(a.1?)><!ELEMENT Special(a.1)><!ELEMENT Special EMPTY> |
| 1つ以上 (+) | 名前変更、必須への変更、必須エレメントと他のエレメントへの分割、1つ以上のエレメントと他のエレメントへの分割 | <!ELEMENT General(a+)> <!ELEMENT Special(a.1+)><!ELEMENT Special(a.1)><!ELEMENT Special(a.1,a.2,a.3+,a.4*)><!ELEMENT Special(a.1+,a.2,a.3*)> |
| ゼロ個以上 (*) | 名前変更、必須への変更、オプションへの変更、必須エレメントと他のエレメントへの分割、オプション・エレメントと他のエレメントへの分割、1つ以上のエレメントと他のエレメントへの分割、ゼロ個以上のエレメントと他のエレメントへの分割、削除 | <!ELEMENT General(a*)> <!ELEMENT Special(a.1*)><!ELEMENT Special(a.1)><!ELEMENT Special(a.1?)><!ELEMENT Special(a.1,a.2,a.3+,a.4*)><!ELEMENT Special(a.1?,a.2,a.3+,a.4*)><!ELEMENT Special(a.1+,a.2,a.3*)><!ELEMENT Special(a.1*,a.2?,a.3*)><!ELEMENT Special EMPTY> |
| 排他的論理和 | 名前変更、いずれか1つを選択 | <!ELEMENT General (a|b)> <!ELEMENT Special (a.1|b.1)><!ELEMENT Special (a.1)> |
コンテンツ・モデル (a,b?,(c|d+)) を持つ一般的なエレメント
General
があるとします。この定義の意味は、
General
に常にエレメント
a
が含まれ、オプションでエレメント
b
が後に続き、常に最後が
c
または1つ以上の
d
であるということです。
リストA. 一般エレメントGeneralのコンテンツ・モデル
<!ELEMENT General (a,b?,(c|d+))>
|
General
を特殊化して
Special
を作成する場合、そのコンテンツ・モデルはGeneralと同じかそれ以上に限定的でなければなりません。つまり、
General
が許可するよりも多くのものを許可することはできません。そうでないと、上向きにマップすることや、一般的なプロセス、トランスフォーム、またはスタイル・シートの正しい動作を保証することができなくなります。
名前変更 (常に許可される。ここでは、
Special
に含めることができる一部のエレメントを特殊化しているにすぎない) を別にして、
Special
のコンテンツ・モデルに加えることが可能ないくつかの有効な変更を次に示します。これにより、コンテンツ規則は前と同じかより限定的になります。
リストB. モデルSpecialへの有効な変更。bを必須にする
<!ELEMENT Special (a,b,(c|d))>
|
この
Special
では、
b
がオプションでなく必須になり、許可される
d
は1つだけになります。これは、
General
に安全にマップされます。
リストC. モデルSpecialへの有効な変更。cを必須にし、dを禁止する
<!ELEMENT Special (a,b?,c)>
|
この
Special
では、
c
が必須になり、
d
が許可されなくなります。これは、
General
に安全にマップされます。
リストD. モデルSpecialへの有効な変更。dを特殊化した3つのものを必須にする
<!ELEMENT Special (a,b?,d1,d2,d3)>
|
この
Special
では、
d
を特殊化した3つのものが必須になり、
c
は許可されません。これは、
General
に安全にマップされます。
-
developerWorks で
Darwin Information Typing Architectureの紹介
をご覧ください。
-
Don DayとMichael Priestleyが司会する
DITAフォーラム
での討論に加わる方法をお調べください。
-
Don DayとMichael Priestleyが司会する
DITAフォーラム
に直接アクセスできます。
-
XSLTに関する前提知識を必要とされるならば、Read Michael Kayの技術紹介記事、
What kind of language is XSLT?
をお読みになってください。