<define> 要素に @combine 属性を付加することによって、同等なパターンを別個に書くことができます。
@combine 属性の基本
@combine 要素は以下のように、同名の <define> 要素に付加します。 属性値は「choice」または「interleave」を指定します:
<grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <ref name="xslt"/> </start> <define name="xslt" combine="choice"> <element name="stylesheet">...</element> </define> <define name="xslt" combine="choice"> <element name="transform">...</element> </define> </grammar>
このスキーマ定義は以下のような、<define> 要素が1つのものと等価です:
<grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <ref name="xslt"/> </start> <define name="xslt"> <choice> <element name="stylesheet">...</element> <element name="transform">...</element> </choice> </define> </grammar>
幾つか注意を:
- <define> 要素下の <choice> 要素は、@combine 要素で指定したものと同じになります。 @combine 要素に「interleave」を指定すると、<define> 要素下には <interleave> 要素が付加されます。
- 同名の <define> 要素はいくつでも書くことができますが、@combine 要素の値は全て同じでなければなりません。 ただし、1つの <define> 要素だけ @combine 属性を省略することができます*1。
- パターンの参照の仕方(<ref> 要素の書き方)は @combine 要素のあるなしで変わりありません。
<include> 要素との併用
<include> 要素は他ファイルに定義された <define> 要素を読み込む要素でした。 これと @combine 属性を付加した <define> 要素を併用することで、既存のスキーマ定義を拡張することができます。
まず、以下のようなスキーマ定義があったとしましょう(xslt.rng):
<!-- xslt.rng --> <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <ref name="xslt"/> </start> <define name="xslt"> <element name="stylesheet">...</element> </define> </grammar>
このスキーマ定義を拡張して、ルート要素が <transform> でも良いようにするには、以下のようにします:
<!-- xslt-ex.rng --> <grammar xmlns="http://relaxng.org/ns/structure/1.0"> <include href="xslt.rng"/> <start> <ref name="xslt"/> </start> <define name="xslt" combine="choice"> <element name="transform">...</element> </define> </grammar>
これは前節のスキーマ定義と等価なものになります。 参照先の <define> 要素には @combine 属性がいらないことに注意しましょう。
*1:これは <include> 要素と併用する際に必要な機能です。