optional 要素
出現の有無を任意にする要素
- 子要素に記述される一聯のパターンに関し、それらのパターンの出現を任意にする要素です。具体的に言えば、0回もしくは1回の出現を指示する働きを持ちます。
- とりわけ attribute要素 の親要素として用いることで、属性をオプション扱いとして定義出来ます(DTD では #IMPLIED の宣言に相当)。
- attribute要素 の子孫要素としては用いることが出来ません。
- コンテナ や サブコンテナ (XMLなら要素属性値、要素の中身) など様々な定義の中で使うことが出来ます。
- grammar 要素の直下には置いてはなりません。
- スキーマのルート要素に用いることが出来ます。ただし、そのスキーマは単独では用いることは出来ず、 externalRef 要素の参照先としてのみ利用できます。
属性
lang:occurs 属性
名前空間 lang に属する属性です。optional 内の処理を実行するかどうかを、事前に設定してください。
- decode : 「1」であれば、optional 内の処理を実行します。
- encode : 「1」であれば、optional 内の処理を実行します(encode 時は必須です)。
lang:occured 属性
名前空間 lang に属する属性です。optional の処理の後に設定されます。
- decode : optional 内の処理を実行できた場合は「1」、 実行できなかった場合は「0」が、指定された変数に代入されます。
- encode : 指定できません。
制約
- optional、oneOrMore、zeroOrMore を入れ子にできる最大数は、「32」です。
- ref 要素を中身にし、マクロを参照することが出来ます。 ただし、ソースコードの生成前に、define/ref が展開されている必要があります。
- lang:occurs 属性と、lang:occured 属性を同時に指定することはできません。 どちらか一方を必ず指定してください。
- occurs 属性に 0 または 1 以外の値を指定することはできません。エラーとなります。
子ノード
- 複数の コンテナ もしくは サブコンテナ を子要素に持つことが出来ます。
- interleave要素, optional要素, zeroOrMore要素 などを子に持つことも可能です。
考えてみよう!
その 1: 連続する optional要素
連続する optional要素 の中身を、一つの optional要素 の中身としてまとめることは出来ません。以下に、その例を示します。
- 例1
-
<optional> <ref name="a"/> </optional> <optional> <ref name="b"/> </optional>
- 例2
-
<optional> <ref name="a"/> <ref name="b"/> </optional>
例1では、「aとbそれぞれが任意出現パターン」であるのに対し、例2では、「aとbとの並びが任意出現」となります。それぞれのパターンを任意出現パターンとして定義したい場合は、面倒でも独立した optional要素 の子要素として記述しなければなりません。
その 2: 出現順番に関して
choice要素, interleave要素 の子要素でない場合、定義の出現順番は保持されます。例えば、以下のスキーマを考えます。
<element name="p"> <optional> <element name="a"><empty/></element> </optional> <optional> <element name="b"><empty/></element> </optional> </element>
上記のスキーマに則った場合、以下の文書は妥当とはなりません。
<p><b/><a/></p>
つまり「オプション扱い」になると言っても、順序まで任意になるわけではないので、注意してください(順序を任意にしたい場合は、choice要素, interleave要素 の子要素とする必要があります)。
参考文献
- James Clark and Makoto Murata, ISO/IEC FDIS 19757-2 Document Schema Definition Language (DSDL) -- Part 2: Regular-grammar-based validation -- RELAX NG
- 古林 寛, 「optional要素 @ ぽかぽか RELAX NG 工房」