!
人手で検証を行った後、AIが記事を執筆しました。
はじめに#
TEI(Text Encoding Initiative)XMLを編集する際、要素や属性の構造検証だけでなく、より複雑なビジネスルールの検証が必要になることがあります。本記事では、RELAX NG(RNG)とSchematronを組み合わせて、構造検証と内容検証の両方を実現する方法を、実際のプロジェクトで直面した課題を例に解説します。
解決したい課題#
日本の古典文学テキストをTEI XMLで校訂する際、以下のような要求がありました:
- ID参照の動的検証 :
corresp属性で参照するIDが、実際に文書内のwitness要素に存在することを検証したい - Oxygen XML Editorでの補完機能 : 編集時にIDの候補を自動表示したい
- 複数ID参照のサポート : スペース区切りで複数のIDを指定可能にしたい
- 特定要素のみ参照を許可 :
witness要素のIDのみを参照可能とし、person要素のIDが含まれる場合はエラーにしたい
なぜRNG + Schematronなのか?#
RELAX NGの得意分野#
- 要素・属性の構造定義
- データ型の指定
- 基本的な内容モデルの定義
Schematronの得意分野#
- XPathベースの複雑な検証ルール
- 文書内の相互参照チェック
- カスタムエラーメッセージの提供
この2つを組み合わせることで、構造と内容の両面から厳密な検証が可能になります。
実装例#
1. 基本的なRNGスキーマ構造#
2. ID定義とanyURI型の活用#
Oxygen XML Editorで自動補完を実現するために、anyURI型を使用します:
ポイント :
data type="ID"で一意性を保証data type="anyURI"で#付きの内部参照を許可list要素でスペース区切りの複数値を許可
3. Schematronによる高度な検証#
ポイント :
sch:letで変数を定義し、XPathで動的に値を取得tokenize()で複数ID参照をパースsch:assertで条件を満たさない場合にエラーsch:reportで条件を満たす場合にエラーrole="error"でエラーレベルを指定(warning、info も可能)
4. 実際の使用例#

実装時の注意点#
1. XPath 2.0の構文#
Schematron内のXPath式では、for式の構文に注意が必要です:
2. IDREF vs anyURI#
- IDREF型 :
#を含めることができず、Oxygenでの補完が制限される - anyURI型 :
#付きの値を許可し、Oxygenが自動的にID補完を提供
3. Schematronのrole属性#
role="error": 赤色のエラーマーカーrole="warning": 黄色の警告マーカーrole="info": 青色の情報マーカー
応用例#
複雑な相互参照の検証#
条件付き必須属性#
まとめ#
RELAX NGとSchematronを組み合わせることで:
- 構造検証と内容検証の分離 : それぞれの得意分野を活かした設計が可能
- 動的な検証ルール : 文書の内容に基づいた柔軟な検証
- エディタ支援 : Oxygen XML Editorなどでの高度な編集支援
- わかりやすいエラーメッセージ : 日本語でのカスタムメッセージ
特にTEI XMLのような複雑な構造を持つ文書の編集において、この組み合わせは非常に強力なツールとなります。
参考資料#
この記事で紹介したスキーマの完全なコードは、実際のプロジェクトで使用されているものです。同様の課題を抱えている方の参考になれば幸いです。