define 要素
マクロを定義する要素
- 一聯のパターンをマクロ(外部から参照させるための「部品」)として利用したい場合、そのパターン群を define要素 の中身とします。いくつかのファイルに分けて「モジュール」を作りたい場合、必携の要素となります。
- define要素 の中身は、常に ref要素 から参照されます。 externalRef要素, include要素 などでは参照出来ません。
- 常に grammar要素 もしくは include要素 の子要素として記述しなければなりません。 define要素 を入れ子にしたり、各種パターン要素の子要素としたりしてはなりません。
- 通常は、同一ファイル内で define要素 と ref要素 が対応します。 ただし、include要素 を用いて外部ファイルの取り込みを行っている場合は、参照元(ref要素) と参照先(define要素) が異なるファイル内に存在しても構いません。ただし、 ref要素 の参照先が取り込みファイルの中に存在しない場合はエラーとなります。
同じ名前を持つ複数の define要素
- grammar要素 の子要素として記述する場合は、combine 属性 で結合法則を明示しなければなりません。combine 属性 には、 choice もしくは interleave どちらかの値を取ることが出来ます。
- include要素 の子要素として記述する場合は、「定義の上書き」のみが可能です。当然マクロの名前は、 参照先の外部ファイルの中に含まれていなければなりません。新たなマクロの定義や、combine 属性 を用いた「定義の結合」は出来ません。
属性
name 属性
マクロの名前を定義します。name 属性 の属性値は NCName となっているため、名前空間が異なる要素/属性宣言の中でも、同じ名前を使って参照することが出来ます。ただし、接頭辞と名前を区切るための : は使用出来ません。ピリオドやハイフン、アンダースコアは利用できます。尚、大文字小文字は区別されるので、注意してください。
combine 属性
結合法則を明示します(詳しくは後述)。
子ノード
- 空の define要素 はあまりよろしくないと思います。モジュールの組み込みにおいて「記述不可能」の旨の初期値を定義したい場合は、empty要素 を子要素に入れるのが最適でしょう。ただし、ここで notAllowed要素 を用いるとややこしいことになるので、注意が必要です (詳しくは「notAllowed要素 の解説」にて)。
- 全てのパターン関聯要素もしくは element要素, attribute要素 などを子要素にすることが可能ですが、してはいけないものもあります。例えば、要素/属性名の排他定義(◎◎と△△以外の全ての要素を中身にするような定義)の中では、 define, ref 各要素によるマクロの取り込みが出来ません。例えば、次のような記述は不可能です。
<element> <anyName> <except> <!-- except 要素による排他法則の定義 --> <ref name="exceptRule"/> <!-- 取り込み不可能!! --> </except> </anyName> .... </element> <define name="exceptRule"> <choice> <name>abc</name> <name>def</name> </choice> </define>
ただし、ref要素, define要素 を使わず、直截 define要素 の中身を except要素 の中に記述すれば、全く問題はありません。
使用例
例 1: define要素 と include要素 を用いた例
- ファイル1: schema1.rng
-
<?xml version="1.0"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <element name="document"> <ref name="para"/> <!-- マクロの参照 --> </element> </start> <include href="schema2.rng"/> <!-- 外部ファイル取り込み --> <define name="para" combine="choice"> <element name="strong"><empty/></element> </define> </grammar>
- ファイル2: schema2.rng
-
<?xml version="1.0"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <define name="para"> <!-- 外部ファイル中の define 要素 --> <element name="em"><empty/></element> </define> </grammar>
例 2: 上記と等価なスキーマ
上記のスキーマをマクロを使用しないで記述した場合、以下のようになります。
<?xml version="1.0"?> <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <element name="document"> <choice> <!-- define 要素の combine 属性による効果 --> <element name="strong"><empty/></element> <element name="em"><empty/></element> </choice> </element> </start> </grammar>
参考文献
- James Clark and Makoto Murata, ISO/IEC FDIS 19757-2 Document Schema Definition Language (DSDL) -- Part 2: Regular-grammar-based validation -- RELAX NG
- 古林 寛, 「define要素 @ ぽかぽか RELAX NG 工房」