ENGLISH | JAPANESE |
<< | リラックスのしかた/第一部: RELAX Core/STEP 8: tagとattPool再訪 | >> |
tag
が属性リスト宣言に相当し,attPool
が属性だけを定義するパラメータ実体に相当すると説明しました.実際には,より一般的な考え方がRELAXでは存在しています.tag
要素は,name
属性のほかに,role
属性を持つことができます.この節では,まずこの拡張の動機を説明し,つぎにrole
属性を導入します.val
という要素のtype
属性の値によってval
の内容モデルを変えたいとします.type="integer"
と指定されていれば内容モデルはデータ型integer
への参照ですし,type="string"
と指定されていればデータ型string
への参照です.
<!-- This is legal. --> <val type="integer">10</val> <!-- This is also legal. --> <val type="string">foo bar</val> <!-- This is illegal. --> <val type="integer">foo bar</val> |
したがって,type
属性の値がinteger
かstring
かで,次の二つのelementRule
を使い分けたくなります.
<!-- Case 1: type="integer" --> <elementRule role="val" type="integer"/> <!-- Case 2: type="string" --> <elementRule role="val" type="string"/> |
しかし,STEP 7までの機能では,タグ名に対して内容モデルを記述しています.属性値は使われません.したがって,type
属性の値に関わらず,同じelementRule
が適用されてしまいます.
tag
要素は,name
属性のほかに,role
属性を持つことができます.tag
の基本的な形は次の通りです.name
属性はタグ名を指定しますが,role
属性が指定するのは役割です.
<tag name="tag-name" role="role-name"> ... </tag> |
tag
要素は,タグ名と属性に関する制約条件の集まりを役割に関連づけます.tag
要素に記述された条件を開始タグ(または空要素タグ)が満たすとき,このタグは指定された役割を持つと言います.
例として,次のtag
要素を考えます.
<tag name="val" role="val-integer"> <attribute name="type" type="NMTOKEN" required="true"> <enumeration value="integer"/> </attribute> </tag> |
このtag
要素は,「タグ名がval
であり,type
属性の値はinteger
という文字列である」という制約条件を表しています.この条件を満たす開始タグ(または空要素タグ)は,役割val-integer
を持ちます.したがって,次の開始タグは,役割val-integer
を持ちます.
<val type="integer"> |
次のtag
要素では,type
属性の値に関する条件が「値がstring
という文字列である」に変わり,役割がval-string
に変わっています.
<tag name="val" role="val-string"> <attribute name="type" type="NMTOKEN" required="true"> <enumeration value="string"/> </attribute> </tag> |
次の開始タグは役割val-integer
は持ちませんが,役割val-string
は持ちます.
<val type="string"> |
tag
要素によって指定されていない属性があっても構いません.たとえば,次の開始タグの属性unknown
は,先のtag
要素で言及されていません.しかし,この開始タグは,役割val-string
を持ちます.ただし,診断メッセージは出力されます.
<val type="string" unknown=""> |
STEP 1から7までにあるようなrole
属性がないtag
要素はどう解釈されるのでしょうか.role
属性がない場合は,name
属性と同じものが指定されたものとみなされます.したがって次の二つのtag
要素は同じ意味を持ちます.
<tag name="foo"> <attribute name="bar" type="int"/> </tag> <tag name="foo" role="foo"> <attribute name="bar" type="int"/> </tag> |
elementRule
要素のrole
属性は,タグ名を指定するのではなく役割を指定します.したがって,タグ名が同じであっても属性が違えば,別の生け垣モデルを使うことができます.val-string
とval-integer
を使えば,タグ名がval
である開始タグに対して二つのelementRule
を使い分けることが出来ます.述語名val-string
を指定するelementRule
ば,type
属性の値がstring
である開始タグを扱います.役割val-integer
を指定すれば,type
属性の値がinteger
であるものを扱います.
<!-- Case 1: type="integer" --> <tag name="val" role="val-integer"> <attribute name="type" type="NMTOKEN" required="true"> <enumeration value="integer"/> </attribute> </tag> <elementRule role="val-integer" label="val" type="integer"/> <!-- Case 2: type="string" --> <tag name="val" role="val-string"> <attribute name="type" type="NMTOKEN" required="true"> <enumeration value="string"/> </attribute> </tag> <elementRule role="val-string" label="val" type="string"/> |
二つのtag
要素がタグ名val"
と属性名"type
を指定していることに注意して下さい.RELAXにおけるtag
要素は,一度だけしか行われない宣言ではなく,何度でも書ける制約条件なのです.
ref
要素が参照する役割を,tag
要素で記述してはいけません.記述するのなら,attPool
要素で記述する必要があります.ref
要素は,tag
要素によって記述された役割foo
を参照しています.したがって,構文エラーです.
<tag name="foo"/> <attPool role="bar"> <ref role="foo"/> </attPool> |
none
を導入しました.属性が指定された場合と指定されない場合とで異なる内容モデルを用いるときに,none
は有益です.<div class="sec">
と<div>
で内容モデルを変えることを考えます.前者を表現する役割divSec
は次のように記述されます.
<tag name="div" role="divSec"> <attribute name="class" type="string"> <enumeration value="sec"/> </attribute> </tag> |
問題は<div>
を表現する役割divWithoutClass
をどう記述するかです.次のように記述したとします.
<tag name="div" role="divWithoutClass"/> |
この記述では,<div class="sec">
に対しても,divWithoutClass
が成立してしまいます.宣言されていない属性があるというメッセージは出ますが,両方の役割を持つとみなされてしまいます.(1)
属性class
を持たないということを陽に指定するには,データ型none
を用いて次のように書く必要があります.
<tag name="div" role="divWithoutClass"> <attribute name="class" type="none"/> </tag> |
データ型none
に属する文字列は存在しないので,どんな値を属性class
に指定しても役割divWithoutClass
を持つことはありません.
attPool
要素は,パラメタ実体のように単に展開されるものではありません.attPool
要素は,tag
要素とほとんど同等の概念です.tag
要素は,タグ名に関する制約条件と属性に関する制約条件の集まりに役割を関連付けるものでした.attPool
要素もほとんど同じで,違いはタグ名に関する制約条件を指定できないことだけです.すなわち,属性に関する制限の集まりに役割を関連付けるものがattPool
要素です.attPool
を考えます.
<attPool role="info"> <attribute name="class" required="true"> <enumeration value="informative"/> </attribute> </attPool> |
このattPool
要素は,「class
という属性が指定されており,その値はinformative
という文字列である」という条件にinfo
という役割を関連付けています.タグ名が何であっても構いません.このattPool
によって,次の空要素タグは役割info
を持ちます.
<some class="informative"/> |
tag
要素のときと同様に,宣言されていない属性があっても構いません.たとえば,次の開始タグに対して役割info
は成立します.
<some class="informative" unknown=""/> |
elementRule
要素のrole
属性で指定する役割を,attPool
要素で記述してはいけません.記述するのなら,tag
要素で記述する必要があります.elementRule
は役割info
を参照しています.役割info
はattPool
要素によって規定されています.したがって,この例は構文エラーです.
<attPool role="info"/> <elementRule role="info" label="informative" type="emptyString"/> |
tag
またはattPool
要素が,一つの役割を共有することはできません.tag
要素が役割bar
を共有しています.したがって,構文エラーです.
<tag name="foo1" role="bar"> <attribute name="a" type="string"/> ... </tag> <tag name="foo2" role="bar"> <attribute name="b" type="string"/> ... </tag> |
以下の例では,役割とタグ名の両方を共有しています.これも構文エラーです.
<tag name="foo" role="foo"> <attribute name="a" type="string"/> ... </tag> <tag name="foo" role="foo"> <attribute name="b" type="string"/> ... </tag> |
role
属性が省略され,name
属性の値が使われたときも,共有は許されません.次の二つのtag
要素は,上の二つのtag
要素と同じ意味を持ちます.したがって,この例も構文エラーです.
<tag name="foo"> <attribute name="a" type="string"/> ... </tag> <tag name="foo"> <attribute name="b" type="string"/> ... </tag> |
つぎの例では,二つのattPool
要素が役割bar
を共有しています.したがって,構文エラーです.
<attPool role="bar"> <attribute name="a" type="string"/> ... </attPool> <attPool role="bar"> <attribute name="b" type="string"/> ... </attPool> |
最後に,tag
要素とattPool
要素が役割bar
を共有した例を示します.これも,構文エラーです.
<attPool role="bar"> <attribute name="a" type="string"/> ... </attPool> <tag role="bar" name="foo"> <attribute name="b" type="string"/> ... </tag> |
tag
要素はタグ名と属性を宣言するものだと見なしてきました.本当は,タグ名に関する条件と属性に関する条件に役割を関連づけるのがtag
要素です.これまでは,役割とタグ名は常に同じでしたが,必ずしもそうではありません.多くの場合にはラベルと役割とタグ名には一対一に対応しますが,一般的にはそうではありません.構文要素 | タグ名/ラベル/役割の区別 |
elementRule のrole 属性 |
tag で記述された役割への参照 |
elementRule のlabel 属性 |
ラベルの記述 |
hedgeRule のlabel 属性 |
ラベルの記述 |
ref のlabel 属性 |
elementRule によって記述されたラベルへの参照 |
hedgeRef のlabel 属性 |
hedgeRule によって記述されたラベルへの参照 |
tag のname 属性 |
タグ名の記述 |
tag のrole 属性 |
役割の記述 |
attPool のrole 属性 |
役割の記述 |
ref のrole 属性 |
attPool によって記述された役割への参照 |
名前の種類 | インスタンス中で | RELAXモジュール中で |
タグ名 | 出現する | 節の一部として出現する |
役割 | 出現しない | 節の一部として出現する(役割の記述と参照) |
ラベル | 出現しない | 生成規則の一部として出現する(ラベルの記述と参照) |
role
属性だけです.RELAXの簡潔さ,強力さの現れといっていいでしょう.RELAX!<< | リラックスのしかた/第一部: RELAX Core/STEP 8: tagとattPool再訪 | >> |