このセクションでは、もっと先進的なルールのシンタックスを説明します。
これまでに説明したルールのシンタックスは、データソースによっては役立ちますが、時には、データをもっと複雑な方法で表示する必要があるでしょう。単純なルールシンタックスは、実は、以下で説明する完全なルールシンタックスにとって、ショートカットでしかありません。単純なルールと同様に、完全なルールも、rule タグ内に置かれます。
完全なルールは、3 つの子供タグをもちます。conditions タグ、bindings タグ、action タグです。このうち、bindings はいつも必要という訳ではありません。
conditions 要素は、あるリソースにマッチするかどうかの基準を指定するのに使います。そのすべてがマッチしなければならない多数の条件を指定することができます。単純なルールシンタックスでは、条件は、直接、rule 要素自身の内部に置かれます。
条件がリソースにマッチすると、actions タグ内に置かれた内容が生成されます。単純なシンタックスでは、内容は、直接、rule の内部に置かれます。
データソースをもつツリーやメニュー、その他の要素が内容を生成する場合、テンプレートビルダーは、まず、ref 属性が参照しているリソースを見付けます。次いで、その検索は、そのリソースの子供リソースすべてで繰り返されます。個々のリソースは、条件にかけられます。条件がリソースにマッチすると、actions 要素の内容がそのリソースのために生成されます。条件がマッチしない場合は、内容は何も生成されません。
conditions 要素は、3 つの要素をもつことができます。最初は、content 要素で、これは、常に、一度だけしか存在しないようにすべきです。これは、テンプレートビルダーがリソースすべてを繰り返し処理する場合にプレースホルダーとして役立ちます。そこには、条件がマッチするか分析される間、ルートリソースへの参照が置かれる変数名を指定します。ルートリソースは、テンプレートを含む要素の ref 属性によって指定されるリソースです。
content 要素のシンタックスは次の通りです。
<content uri="?var"/> |
クエスチョンマークは、その後に続くテキストが変数であることを示します。こうすると、条件の残りの部分の中で、変数 'var' を使うことができます。もちろん、変数名は、お望みのどんな名前にしても構いません。
次の要素は、member 要素です。これは、子供リソースセットで繰り返し処理をするのに使われます。RDF の用語では、これは、Seq、Bag、Alt などのコンテナの意味です。例えば、次の短い RDF コードに記述された都市のリストが取得できるでしょう。
<RDF:Seq about="urn:cities"> <RDF:li resource="urn:cities:Paris"/> <RDF:li resource="urn:cities:Manchester"/> <RDF:li resource="urn:cities:Melbourne"/> <RDF:li resource="urn:cities:Kiev"/> </RDF:Seq> <RDF:Description about="urn:cities> <cityset:name>Paris</cityset:name> </RDF:Description> . . . |
ツリーの行に個々の都市を表示したいとします。このためには、次のように、member 要素を使います。
<tree id="citiesTree" datasources="cities.rdf" ref="urn:cities">
<template>
<rule>
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
</conditions>
<rule>
<template>
</tree>
|
テンプレートビルダーは、ref 属性の値を取得することから始めます。この場合は、urn:cities です。このリソースは、content タグによって指定された 'list' 変数内に置かれます。'list' 変数を使うことで、ルートリソースに関連するリソースが取得できます。
テンプレートビルダーは、次に、member 要素を見ます。これによって、ビルダーは、要素の子供を繰り返し処理します。親は container 属性によって指定され、子供は child 属性によって指定されます。上の例では、container 属性は、変数 'list' です。このため、親は、list 変数の値になります。これはルートリソース 'urn:cities' に設定されています。その結果、'urn:cities' の子供のリストで処理が繰り返されます。
上の RDF を見ると、'urn:cities' リソースには子供が 4 つあり、それぞれ異なった都市を内容としていることが分かります。テンプレートビルダーは、子供のそれぞれを繰り返し処理し、子供を child 属性に対してマッチさせます。この場合、それは、変数 'city' に設定されているだけです。そのため、ビルダーは、'city' 変数を、順に、個々の子供リソースに設定します。
これ以上の条件はないので、条件は、これら 4 つのリソースの各々にマッチし、ビルダーは、4 つのそれぞれの内容を生成します。もちろん、上の例には、内容は何もありません。後で内容を追加することにしましょう。
次の要素は、triple 要素です。これは、RDF リソース内にある種のトリプル (triple) (あるいはアサーション (assertion)) があるかチェックするために使われます。トリプルとはリソースのプロパティーのようなものです。例えば、トリプルは、ブックマークとその URL の間に存在します。これは次のように表現できるかもしれません。
A Bookmark to mozilla.org --> URL --> www.mozilla.org
これは、ブックマーク 'A Bookmark to mozilla.org' とその URL プロパティーである 'www.mozilla.org' の間にトリプルがあることを意味します。この表現の最初の部分は、サブジェクト、2 番目の部分はプレディケート、最後の部分はオブジェクトと呼ばれます。triple 要素として、これは、次のように表現されるでしょう。
訳注: 上の名称を日本語にすると、それぞれ、主語、述語、目的語になります。このように訳すと、それが、トリプルの構成部分の呼び名であることが分かりにくくなるのでカタカナで表記しました。ちなみに、トリプルとは、3 つの要素が関連しあっていることを指しています。適切な訳語が思い浮かばなかったのでそのままカタカナで表記しました。
<triple subject="A Bookmark to mozilla.org"
predicate="URL"
object="www.mozilla.org"/>
|
これは、実際のものより少々単純化してあります。プレディケートは、通常は、ネームスペースを含みます。そしてサブジェクトは、ここで使われているようなブックマークのタイトルではなく、ブックマークのリソース id となるでしょう。実際は、ブックマークのタイトルは、ネームプレディケートを使ったデータソース内の別のトリプルとなるでしょう。
triple 要素のサブジェクトとオブジェクトは、変数参照で置き換えることができます。その場合、値は変数で置き換えられます。その変数の値がまだ定義されていない場合、テンプレートビルダーは、データソース内の値を探し、それを変数に割り当てます。
都市データソースに天気予報を追加したいとしましょう。以下の条件が使えるかもしれません。
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="?pred"/>
</conditions>
|
テンプレートビルダーは、前と同様に、個々の都市を繰り返し処理します。トリプルに辿り着くと、それは、RDF データソース内で、都市の天気予報に関するアサーションを探します。変数 'pred' は、その予報を割り当てられます。ビルダーはこれを 4 つの都市それぞれで繰り返します。マッチすると、ビルダーは、予報のある個々の都市のための内容を生成します。都市に予報リソースがなければ、条件にマッチせず、その都市のための内容は何も生成されません。プレディケートの先頭に 'rdf:' を置く必要がない点に注意して下さい。それは前提されているからです。
object は、インラインの値で置き換えることもできます。例えば
<conditions>
<content uri="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="Cloudy"/>
</conditions>
|
この例は、前の例と似ていますが、'Cloudy' にマッチさせたいことを指定しています。その結果、条件は、予報が 'Cloudy' である都市にだけマッチします。
もっとマッチさせるためにトリプルを追加することができます。例えば、上の例で、気温と風速をチェックしたいとしましょう。このためには、追加リソースをチェックする別のトリプルを加えるだけです。条件は、トリプルすべてが値を提供する場合に、マッチします。
下の例は、都市の名前のための別のトリプルをチェックします。これは、'name' 変数に代入されます。条件は、都市に名前と予報の両方がある場合にだけマッチします。
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="?pred"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#name"
object="?name"/>
</conditions>
|
あるルールのために生成する内容は、action 要素内に指定します。これは、ツリーやメニュー項目の行のための内容、あるいは生成したいどんな内容であっても構いません。内容の中では、条件で定義した変数を参照することができます。このため、上の天気の例では、都市や予報を表示するため、変数 'name' や 'pred' が使えます。'list' や 'city' 変数を使うこともできます。しかし、それらは、テキストではなくリソースを保持しています。そのため、それらは、おそらく、ユーザーにとって意味ある値ではないでしょう。
単純なルールシンタックスでは、内容が生成されるべき場所を指示するのに、uri='rdf:*' シンタックスを使います。完全なシンタックスでは、条件内で使った変数に uri の値を割り当てます。通常、これは、member 要素の child 属性に割り当てられた変数です。
以下の例は、条件とアクションをもつ完全なツリーを示しています。これとは別に、RDF ファイルを見る こともできます。
例 6.8.1
<tree id="weatherTree" flex="1" datasources="weather.rdf" ref="urn:weather:cities">
<template>
<rule>
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="?pred"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#name"
object="?name"/>
</conditions>
<action>
<treechildren flex="1">
<treeitem uri="?city">
<treerow>
<treecell label="?name"/>
<treecell label="?pred"/>
</treerow>
</treeitem>
</treechildren>
</action>
</rule>
</template>
</tree>
|
2 つのカラムがこのツリー内に表示されます。一方は、個々の行に、name 変数の値を表示し、もう一方は、pred 変数の値を表示します。
ルール内に追加できる最後の要素は、bindings 要素です。この内部には、一つかそれ以上の binding 要素を置きます。ルール内のバインディングは、トリプルと同じシンタックスで、それとほとんど同じ機能を実行します。例えば、上の天気の例には、次のバインディングを加えることができます。
<bindings>
<binding subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#temperature"
object="?temp"/>
</bindings>
|
このバインディングは、個々の都市の気温リソースを取得し、それを 'temp' 変数に割り当てます。これは、トリプルがするのと同じです。違いは、バインディングは、条件をチェックする際に、検査されないということです。これは、都市には表示する名前と予報がなければならないが、気温があるかどうかは問題ではないということです。しかし、都市に気温があれば、それは、'temp' 変数に置かれ、アクションで使うことができます。都市に気温がなければ、'temp' 変数は、空文字列に設定されます。
(進む) 次は、XUL 要素の状態を保存する方法を見ることにしましょう。
例: 6.8.1