DITAとは?構造化文書と再利用の基本
· 小村 豪 · DITA, XML, 技術文書, KCS, Markdown
DITAは、文章を「どんな役割の情報か」で構造化し、必要な順序で組み立てるための標準です。XMLのタグを増やすことより、知識の単位と公開形式を分けて扱えることに意味があります。
問題・質問
技術記事の構成を揃えたいとき、全記事の見出しを同じ言葉にするだけでは限界があります。「前提条件」が書かれているのに操作対象の版が分からない、手順の途中に長い概念説明が入り込む、同じ注意事項を複数の記事へコピーして修正漏れが起きる、といった問題は、見出しの統一だけでは解決しません。
一方、記事を解説型・手順型・比較型へ排他的に分類すると、仕組みを説明しながら実装方法も示したい記事が収まりません。この記事で答えるのは、DITAは何を構造化する標準で、複数の情報型が混ざる技術記事をどう扱えるのかという問いです。さらに、XMLで書いた内容を既存のMarkdownサイトへ渡す方法まで見ます。
flowchart TB
accTitle: 記事構造で整理したい三つのもの
accDescr: 記事全体の情報配置、内部の説明単位、公開形式を別々に考える。
A["記事全体の情報配置"] --> B["内部の説明単位"]
B --> C["公開形式への変換"]
図1: 記事の枠、説明の単位、出力形式を分けると、構成を揃えながら内容を混在させられます。
対象環境
対象は、XMLの要素・属性を読める開発者や、技術文書の構成と保守方法を考えている方です。文書型の説明とXML例はOASIS DITA 1.3を基準にします。「現在の最新版」という意味ではなく、この例が使用する版を固定しています。
変換にはDITA Open Toolkit(DITA-OT)4.3.5のmarkdown_githubを使います。この版の実行要件はJava 17以降です。XMLの編集に特定の有償エディターは必要ありませんが、DTDやXML Catalogを認識するエディターなら、書いている最中にも構造上の誤りを見つけやすくなります。参照: DITA-OTのインストール要件。
この記事でKCSの日本語H2を使うのは当サイトの編集規則です。DITAそのものが「問題・質問」などの日本語見出しを強制するわけではありません。また、この構成だけでKCSの運用全体を実施したことにはなりません。
回答・解決方法
DITA(Darwin Information Typing Architecture)は、情報をトピックとして記述し、情報型に応じた構造を与え、再利用・組み立て・出力を行うためのXMLベースの標準です。「何を書く部分なのか」と「画面でどう見せるか」を分けます。段落や表だけでなく、手順の操作をcmd、前提条件をprereqのように表せます。全記事を一つの文書型へ分類する必要はありません。参照: DITAのトピックの定義。
トピックはページではなく、理解・実行できる説明の単位
トピックは、ある目的に対してまとまりを持つ情報の単位です。例えば「共有メモリとは何か」「共有メモリを作成する」「APIの引数を確認する」は、同じ主題に属していても、読者が求める答えが異なります。別々のトピックとして書けば、必要なものを必要な順序で組み合わせられます。
重要なのは、トピックの数とWebページの数を一対一にしないことです。複数のトピックを一つの記事として公開してもよく、同じトピックを別の文書構成から参照することもできます。逆に、見出しが一つ増えたというだけで必ず別ファイルに分割する必要もありません。独立した説明として意味が通るか、再利用時に前後の文脈へ依存しすぎないかを考えます。
flowchart TB
accTitle: トピックと公開ページの分離
accDescr: 概念、操作、参照情報の三つのトピックを一つの記事へまとめる。
A["概念を理解する"] --> D["一つの公開記事"]
B["操作を実行する"] --> D
C["仕様を調べる"] --> D
図2: トピックは情報の単位であり、公開ページの単位と同じとは限りません。
concept・task・referenceを、記事ではなく内部の情報へ使う
DITAの既存の文書型を使うと、情報の役割がソースにも残ります。次の三つを基本にし、どれにも無理なく当てはまらない説明には汎用のtopicを使います。障害の原因と対処を組にするtroubleshootingなどもあります。参照: DITAの情報型と構成例。
| 文書型 | 主な問い | 内容の例 |
|---|---|---|
| concept | 何か、なぜそうなるか | 定義、仕組み、具体例、誤解しやすい点。 |
| task | どう実行するか | 前提条件、操作順序、期待する結果。 |
| reference | 正確な値や仕様は何か | 引数、設定値、構文、仕様の一覧。 |
これらは完成記事の排他的なジャンルではありません。例えば、設定変更の回答の中で、最初にconceptで理由を説明し、taskで実行し、referenceで設定値を引けるようにできます。なお、conceptの標準スキーマが「定義・具体例・非該当例」という固定見出しを要求するわけではありません。文書型の意味と、組織が追加する編集規則は区別します。
flowchart TB
accTitle: 一つの回答に複数の情報型を組み合わせる
accDescr: 理由を理解し、操作を実行し、仕様を確認する順序で情報型を使う。
A["conceptで理由を理解"] --> B["taskで操作を実行"]
B --> C["referenceで仕様を確認"]
図3: 一つの記事の中でも、読者の目的に応じて情報型を切り替えられます。
XMLが整っていることと、DITAの構造に従うことは違う
例えば、次は独立したconceptトピックの小さな例です。ファイル名をhello.ditaとします。タイトル、短い要約、本文があり、本文には段落を置いています。DOCTYPEは、どの文書型で検証するかを示します。DITA-OTは同梱のXML Catalogから対応するDTDを解決するので、この例のためにWeb上からDTDを毎回取得する必要はありません。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE concept PUBLIC "-//OASIS//DTD DITA 1.3 Concept//EN" "concept.dtd">
<concept id="shared-memory" xml:lang="ja">
<title>共有メモリとは</title>
<shortdesc>複数の実行主体から共有されるメモリ領域です。</shortdesc>
<conbody>
<p>共有しても、同時アクセスの整合性が自動的に保証されるわけではありません。</p>
</conbody>
</concept>
開始タグと終了タグが対応していれば、XMLとしては読めるかもしれません。しかし、conceptの本文へ手順専用の要素を好きな位置で追加しても、DITAの内容モデルに従っているとは限りません。XMLパーサーで読めた、DTD検証が通った、技術内容が正しい、は別々の判定です。スキーマは説明内容の真偽まで保証しません。
見出しの階層にも注意が必要です。DITAのsectionは、HTMLの見出しを何段でも入れ子にするための箱ではありません。さらに深い説明単位が必要なら、トピックの階層やマップで表現します。異なる型のトピックを一つのXMLへ混在・入れ子にする場合は、標準のditabase文書型を使えます。参照: section、ditaとComposite文書型。
flowchart TB
accTitle: 三段階の確認は別々のもの
accDescr: XMLの整形式、DITAの構造、技術内容の妥当性を順に確認する。
A["XMLとして読めるか"] --> B["DITAの構造に合うか"]
B --> C["説明と根拠は正しいか"]
図4: スキーマ検証を通っても、技術的なレビューを省略することはできません。
マップは組み立てを決め、再利用はコピーを減らす
DITAマップは、どのトピックをどの順序・階層で扱うかなど、トピック間の関係を記述します。本文を大量にコピーする代わりに、同じ情報を複数の構成から参照できます。トピック内の要素を再利用するconref、参照先をキーで間接化する仕組みなどもあります。単純な文字列置換ではなく、DITAプロセッサーが参照関係を処理します。参照: DITAマップ、再利用とマップの例。
次は、一つのXML文書に含まれるトピックをまとめて扱うマップです。chunk="to-content"による組み立てをDITA-OTに任せ、変換後の見出しを手で足して接合する方式にはしません。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map PUBLIC "-//OASIS//DTD DITA 1.3 Map//EN" "map.dtd">
<map xml:lang="ja">
<title>記事の組み立て</title>
<topicref href="article.dita" chunk="to-content"/>
</map>
再利用には保守上の責任もあります。共有した注意事項を変更すると、それを参照する文書にも影響します。対象製品や版の違いを無視して共有すると、修正漏れではなく誤った共通化が起きます。共通の正本を作るだけでなく、その情報が有効な条件と利用箇所を把握する必要があります。
flowchart TB
accTitle: 正本の再利用と影響範囲
accDescr: 共通トピックを二つの文書から参照すると更新の影響も両方へ届く。
S["共通トピックの正本"] --> A["文書Aのマップ"]
S --> B["文書Bのマップ"]
A --> C["文書Aの出力"]
B --> D["文書Bの出力"]
図5: コピーを減らす代わりに、共有した情報の適用条件と影響範囲を管理します。
DITA-OTで検証し、Markdownへ変換する
Java 17以降とDITA-OT 4.3.5を導入し、ditaコマンドが実行できる状態にします。先ほどの独立したconceptの例をhello.ditaとして保存します。Windowsでは配布物のbin/dita.batを実行できます。
DITA-OTにはMarkdown向けの変換が標準で用意されています。ここではGitHub-Flavored Markdownを選びます。XMLを正規表現でMarkdownへ置換する自作コンバーターは必要ありません。参照: Markdown出力。
flowchart TB
accTitle: DITAから既存サイトまでの変換経路
accDescr: DITA XMLを標準プロセッサーでMarkdownへ変換し、既存サイトの処理へ渡す。
A["DITA XMLとマップ"] --> B["DITA-OTで検証・変換"]
B --> C["生成されたMarkdown"]
C --> D["既存のサイト処理"]
図6: XMLからMarkdownへの変換と、Markdownからサイトへの処理を分けます。
-
ツールの版を確認します。
dita --versionこの例の再現では4.3.5を使います。新しい版へ切り替える場合は、生成物の差分も確認します。
-
DTDに基づく構造検証を実行します。
dita validate --input=hello.dita --processing-mode=strictXMLが読めることだけで済ませず、エラーがあればソースへ戻って修正します。
-
GitHub-Flavored Markdownを生成します。
dita --input=hello.dita --format=markdown_github --output=out --processing-mode=strictマップを使用する文書では、入力を
article.ditamapへ変更します。出力先はソースディレクトリと分けます。 -
生成物を実際のサイトの設定で確認します。
タイトル、見出し階層、コードの言語、表、リンク、図を確認します。この記事のようにレイアウトがH1を出すサイトでは、本文のH1だけを公開用の薄いアダプターで除去し、H2以下を勝手に繰り上げません。
outにMarkdownが生成されます。記事の修正はXMLへ戻して再生成し、生成されたMarkdownを別の正本として編集しません。当サイトでも、この前処理の後は従来のMarkdown・Mermaid・Jekyllの処理へ渡します。Javaは執筆・再生成時の依存関係であり、公開済みの生成物を読む処理とは分離できます。
KCSは外側の枠、DITAは内側の情報構造を担当する
KCSの記事構造は、読者の問題・質問、対象環境、回答・解決方法、必要な場合の原因を区別します。これを本文H2へ対応させ、その内側へDITAのトピックを配置すると、記事の入口を統一しつつ、説明や手順を必要な深さまで展開できます。原因は任意であり、概念解説に架空の障害を作る必要はありません。この記事にも独立した原因節は置いていません。参照: KCS Article Structure。
実装上は、KCSの各フィールドを汎用のtopicにし、「回答・解決方法」の下へconcept、task、referenceを配置できます。この混在にはDITA標準のComposite文書型を使えます。固定するのはH2であって、H3以降の具体的な節名まで一律にするわけではありません。
独自の要素名を定義する特化(specialization)は、DITAの拡張の仕組みです。ただし、既存の文書型と編集規則で足りる場面で、最初から独自スキーマを増やす必要はありません。今回のKCS見出しの制約は、標準DITAの構造検証とは別の公開前チェックとして扱います。
flowchart TB
accTitle: KCSの回答フィールド内にDITAの情報型を置く
accDescr: 記事のH2はKCSで固定し、回答の下で概念、手順、参照情報を使う。
A["KCSの固定H2"] --> B["回答・解決方法"]
B --> C["概念の説明"]
B --> D["実行する手順"]
B --> E["仕様の参照"]
図7: 記事を一つの型へ分類するのではなく、固定枠の内側で情報型を組み合わせます。
意味の構造は残せるが、出力の互換性は別に確認する
DITAを導入しても、Markdown側にDITAの全機能が移るわけではありません。DITA-OTのmarkdown_githubでは、定義リストは用語を太字にしたリストへ変換され、Pandoc形式の属性ブロックやIDなどは省かれます。したがって、見た目が似ていても、意味の区別やアンカーが完全に往復できる形式とは考えない方が安全です。参照: GitHub形式への変換上の注意。
図をMermaidで記述する場合も、図のソースを標準のcodeblockへ入れれば終わりではありません。変換されたコードフェンスにmermaidという言語指定が残るか、既存の図生成器が読める字下げか、生成SVGが記事へ組み込まれるかまで確認します。コード例の山括弧、連続バッククォート、表の区切り文字なども、実際の変換結果を確かめる対象です。
また、DTDが保証するのは文法です。根拠のない説明、危険な手順、条件が抜けた比較を自動的に正してくれるわけではありません。構造化の効果を得るには、適用範囲、一次資料、実測と推測の区別、成功の確認方法といった内容のレビューを継続します。
つまり、DITAの導入は「XMLで書けば良い記事になる」という話ではありません。説明の役割をソースへ残し、組み立てと変換を再現可能にし、機械で確認する範囲と人が判断する範囲を分けるための基盤です。単発の短い記事なら準備の負担が上回ることもありますが、同じ知識を継続的に更新し、複数の文書や言語へ展開する運用では、この分離を検討する価値があります。
flowchart TB
accTitle: 構造検証と公開結果の確認を両方行う
accDescr: 文法と固定見出しを機械で確認し、公開結果と技術内容も別に確認する。
A["文法と見出しの検査"] --> B["生成結果の比較"]
B --> C["表示とリンクの確認"]
C --> D["技術内容のレビュー"]
図8: スキーマ、生成物、実際の表示、内容の正確性を別々に確認します。
参考資料
- OASIS DITA Technical Committee, DITA topics。トピックの役割と情報の単位。
- OASIS DITA Technical Committee, dita。Composite文書型で複数の情報型を混在させる構造。
- OASIS DITA Technical Committee, section。節の内容モデル。
- OASIS DITA Technical Committee, DITA maps。トピックの構成と関係。
- OASIS DITA Technical Committee, A Tour of DITA。情報型、再利用、マップの例。
- DITA Open Toolkit, Installing DITA Open Toolkit。導入とJavaの要件。
- DITA Open Toolkit, Generating Markdown output。出力形式と制限。
- DITA Open Toolkit, Chunk topics。トピックの組み立て処理。
- Consortium for Service Innovation, KCS Article Structure。各フィールドの意味とCauseの任意性。
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
MS14-068で普通のユーザーが管理者になれた理由 ── KerberosのPACと署名検証
MS14-068(CVE-2014-6324)では、一般ユーザーが偽ったグループ情報をKDCが受け入れ、ドメイン管理者として扱われ得ました。PAC、鍵付き署名とチェックサムの違い、権限への反映、修正と検知の限界を解説します。
CurveBall――偽の証明書を、なぜWindowsが信頼してしまったのか? ── CryptoAPIと楕円曲線のパラメーター
CurveBall(CVE-2020-0601)は、偽の証明書を信頼された認証局のものと取り違えるWindowsの脆弱性でした。公開鍵の点と基準点の関係から、署名の計算が正しくても信頼の判定が崩れる理由を解説します。
C#からSTAのCOMを使う専用ワーカーの作り方 ── 生成・呼び出し・イベント・終了を一か所で管理する
UIから呼ぶと固まるSTAのCOMを、専用スレッドへまとめる実装例です。Dispatcherと実行キュー、イベントのUI通知、終了中の要求と解放順を、C#と小さなネイティブCOMのサンプルで確認します。
PrintNightmareはなぜSYSTEM権限を奪えたのか? ── 印刷スプーラーとドライバー導入の境界
PrintNightmare(CVE-2021-34527)は、印刷スプーラーのドライバー導入機能からSYSTEM権限のコード実行に至る脆弱性でした。通常の印刷との違い、DLLが実行される過程、Point and Printとの関係、2021年の対策を解説します。
Zerologonはなぜ認証を突破できたのか? ── Netlogonでゼロが正解になった理由
Zerologon(CVE-2020-1472)では、パスワードを知らない相手がコンピューターになりすませました。AES-CFB8の計算を1バイトずつ追い、ゼロが認証の正解になる理由と、ドメイン全体に被害が広がる仕組みを解説します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- DITAは見出しを揃えるテンプレートですか?
- 見出しだけでなく、情報をトピックとして記述し、情報型に応じた構造を与え、再利用と組み立てを行うためのXMLベースの標準です。
- KCSとDITAは併用できますか?
- KCSを記事全体の情報配置に使い、その内側の概念説明・手順・参照情報をDITAの既存の文書型で記述できます。
- Markdownで動く既存サイトでも使えますか?
- DITA-OTでMarkdownを生成して既存の処理へ渡せます。見出し、コード、図、リンクなどは実際のサイト設定で確認します。