Écrit par Neil Deakin.
Traduit par Julien Etaix (22/07/2004).
Page originale :
http://www.xulplanet.com/tutorials/xultu/advrules.html
Ce paragraphe décrit la syntaxe des règles les plus complexes.
La syntaxe des règles décrites jusqu'ici est utile pour certaines sources de données,
mais l'on a parfois besoin d'afficher les données d'une manière plus sophistiquée.
La syntaxe de règle simple n'est en fait qu'un raccourci pour la syntaxe de règle complète qui est décrite ci-dessous.
Comme pour la syntaxe de règle simple, la règle complète est placée entre des balises
rule
.
Une syntaxe de règle complète contient trois balises filles, une balise
conditions
, une balise bindings
et une balise
action
, bien qu'une balise
bindings
ne soit pas
toujours nécessaire.
L'élément conditions
spécifie le critère qui doit correspondre à une ressource donnée. Vous pouvez spécifier le nombre de conditions,
qui doivent toutes correspondre à la ressource donnée.
En utilisant la syntaxe de règle simple, les conditions sont directement situées sur l'élément
rule
.
Si les conditions correspondent à une ressource, le contenu placé entre les balises
action
est activé.
Dans la syntaxe de règle simple, le contenu est directement placé dans la balise
rule
.
Lorsque qu'un arbre, un menu ou tout autre élément avec une source de donnée génère son contenu,
le générateur de modèle cherche en premier la ressource marquée par l'attribut ref
.
L'opération est ensuite répétée pour l'ensemble des ressources filles.
Il compare chaque ressource aux conditions. Si celles-ci sont vérifiées,
le contenu de l'élément action
est généré pour cette ressource. Si elles ne sont pas vérifiées, rien n'est généré.
L'élément conditions
contient trois sous éléments.
Le premier est l'élément content
qui doit toujours être présent une fois seulement.
Il sert de marqueur lorsque le générateur de modèle parcourt les ressources.
Il indique le nom de la variable dans laquelle est placée une référence à la ressource racine pendant que
les conditions sont analysées.
La ressource racine est celle indiquée par l'attribut ref
dans l'élément
contenant le modèle.
La syntaxe d'un élément content
est la suivante :
<content uri="?var"/>
La point d'interrogation indique que le texte qui suit est une variable. Vous pouvez alors utiliser
la variable var
dans le reste des conditions.
Bien entendu, vous pouvez appeler la variable comme vous le voulez.
L'élément suivant est l'élément member
,
qui est utilisé pour parcourir un ensemble de ressources filles.
En termes RDF, c'est comparable à Seq
, Bag
ou Alt
.
Disons que vous avez une liste de villes comme dans le code RDF/XML suivant :
<RDF:Seq RDF:about="http://www.xulplanet.com/rdf/weather/cities">
<RDF:li RDF:resource="http://www.xulplanet.com/rdf/weather/city/paris"/>
<RDF:li RDF:resource="http://www.xulplanet.com/rdf/weather/city/Manchester"/>
<RDF:li RDF:resource="http://www.xulplanet.com/rdf/weather/city/Melbourne"/>
<RDF:li RDF:resource="http://www.xulplanet.com/rdf/weather/city/Kiev"/>
</RDF:Seq>
<RDF:Description RDF:about="http://www.xulplanet.com/rdf/weather/city/paris">
<cityset:name>paris</cityset:name>
</RDF:Description>
.
.
.
Vous voulez afficher une ligne dans une arborescence pour chaque ville.
Pour accomplir cela, utilisez l'élément
member
comme ceci :
<tree id="citiesTree" datasources="weather.rdf"
ref="http://www.xulplanet.com/rdf/weather/cities">
<template>
<rule>
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
</conditions>
<rule>
<template>
</tree>
Le générateur de modèle commence par récupérer la valeur de l'attribut ref
,
qui dans ce cas est http://www.xulplanet.com/rdf/weather/cities.
Cette ressource va être mise dans la variable list
comme il est indiqué par la balise
content
.
On peut alors obtenir les ressources associées à la ressource racine en utilisant la variable list
.
Le générateur de modèle s'intéresse ensuite à l'élément
member
.
Cela force le générateur à itérer sur les fils d'un élément.
Le parent est indiqué par l'attribut container
et les fils par
l'attribut child
.
Dans l'exemple ci-dessus, la valeur de l'attribut container
est la variable
list
.
Ainsi le parent sera la valeur de la variable list
, qui a la valeur de la ressource racine
http://www.xulplanet.com/rdf/weather/cities.
L'effet induit va être de parcourir à travers la liste des fils de
'http://www.xulplanet.com/rdf/weather/cities'.
Si vous regardez en détail le RDF ci-dessus, la ressource 'http://www.xulplanet.com/rdf/weather/cities' a
quatre filles, une pour chaque ville.
Le générateur de modèle parcourt chacune d'elle, comparant la fille avec la valeur de l'attribut
child
.
Dans le cas présent, celui-ci contient la valeur city. Donc le générateur va donner à la variable
city
la valeur des ressources filles au fur et à mesure.
Comme il n'y a pas d'autres conditions, la condition correspond à chacun des quatre ressources et le générateur va créer du contenu pour chacune des quatre. Bien sûr, l'exemple ci-dessus n'a aucun contenu. On l'ajoutera par la suite.
L'élément suivant est l'élément triple
.
Il est utilisé pour vérifier l'existence d'un triplet (ou assertion) dans la source de donnée du RDF.
Un triplet est comme la propriété d'une ressource. Par exemple, un triplet existe entre un marque-page et son URL associée.
Cela peut-être exprimé ainsi :
Un marque-page vers mozilla.org -> URL -> www.mozilla.org
Cela signifie qu'il existe un triplet entre le marque-page Un marque-page vers mozilla.org et
www.mozilla.org par la propriété URL
.
La première partie est appelée le sujet, la seconde, le prédicat, et la dernière, l'objet.
Exprimé en tant qu'élément triple
,
il serait ainsi :
<triple subject="Un marque-page vers mozilla.org"
predicate="URL"
object="www.mozilla.org"/>
Cela a été un peu simplifié par rapport au code réel. Le prédicat devrait normalement inclure les espaces de nom (namespace), et le sujet devrait être l'identifiant ressource du marque-page, et non pas le titre du marque-page comme ici. En fait, le titre du marque-page devrait être un autre triplet dans la source de donnée qui utiliserait le prédicat 'nom'.
Vous pouvez remplacer le sujet et l'objet dans l'élément
triple
avec des références aux variables, auquel cas les valeurs seront substituées aux variables.
Si aucune valeur n'est définie pour une variable, le générateur de modèle va attribuer la valeur de
la source de donnée à la variable.
Disons par exemple, que l'on veuille ajouter une prédiction météo à la source de données des villes. Les conditions suivantes peuvent être utilisées :
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="?pred"/>
</conditions>
Le générateur de modèle va parcourir chaque ville comme précédemment. Lorsqu'il va en arriver au triplet, il va s'intéresser aux assertions de la source de données RDF pour une prédiction météo. On attribue à la variable pred la prédiction météo. Le générateur va répéter cette opération pour chacun des quatre villes. Une comparaison a lieu et le générateur va crée du contenu pour chaque ville qui a une prédiction météo associée. Si la ville n'a pas de ressource de prédiction, la condition ne correspond pas et aucun contenu ne sera crée pour cette ville. Remarquez que vous n'avez pas besoin de mettre 'rdf:' au début du prédicat, ceci est sous-entendu.
On peut aussi remplacer l'attribut object
avec une valeur statique.
par exemple :
<conditions>
<content uri="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="Nuageux"/>
</conditions>
Cet exemple est similaire mais nous spécifions que nous voulons une comparaison qui s'effectue sur Nuageux. Le résultat obtenu est que la condition ne va s'appliquer que pour les villes dont la prédiction météo est Nuageux.
On peut ajouter davantage de triplet pour réaliser plus de comparaisons. par exemple, dans l'exemple ci-dessus, on peut également vouloir vérifier la température et la vitesse du vent. Pour cela, il suffit d'ajouter un autre triplet qui vérifiera les ressources supplémentaires. La condition va correspondre si et seulement si l'intégralité des triplets retournent des valeurs.
L'exemple ci-dessous va vérifier un triplet supplémentaire concernant le nom de la ville.
Il lui sera attribué une variable name
. La condition va correspondre si la ville a
à la fois un nom et une prédiction météo.
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#name"
object="?name"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="?pred"/>
</conditions>
Le contenu à générer pour une règle est spécifié dans l'élément
action
.
Cela peut être le contenu des lignes d'un arbre, les items de menu ou quoi que vous vouliez générer.
A l'intérieur du contenu, vous pouvez vous référer aux variables qui ont été définies dans les conditions.
Ainsi, dans l'exemple météo ci-dessus, vous pouvez utiliser les variables name
ou pred
pour afficher la ville ou la prédiction météo.
Vous pouvez aussi utiliser les variables list
ou city
mais elles contiennent des
ressources et non du texte, donc elles n'auront pas de sens pour les utilisateurs.
Dans la syntaxe de règle simple, on utilise la syntaxe uri="rdf:*"
pour indiquer l'emplacement où le contenu doit être généré.
Dans la syntaxe de règle complète, on donne la valeur de l'attribut uri
à une variable que l'on a utilisé dans les conditions.
Normalement, ce sera la variable assignée à l'attribut child
de l'élément
member
.
L'exemple suivant montre un arbre complet avec des conditions et une action. Vous pouvez consulter le fichier RDF séparément ( Source RDF).
<tree id="weatherTree" flex="1" datasources="weather.rdf"
ref="http://www.xulplanet.com/rdf/weather/cities">
<treecols>
<treecol id="city" label="Ville" primary="true" flex="1"/>
<treecol id="pred" label="Prédiction Météo" flex="1"/>
</treecols>
<template>
<rule>
<conditions>
<content uri="?list"/>
<member container="?list" child="?city"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#name"
object="?name"/>
<triple subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#prediction"
object="?pred"/>
</conditions>
<action>
<treechildren>
<treeitem uri="?city">
<treerow>
<treecell label="?name"/>
<treecell label="?pred"/>
</treerow>
</treeitem>
</treechildren>
</action>
</rule>
</template>
</tree>
Deux colonnes apparaissent dans cet arbre, l'une qui affiche la valeur de "nom" pour chacun ligne, et l'autre qui affiche le résultat de la prédiction météo.
Si vous utilisez le marqueur dont-build-content (ne-pas-générer-de-contenu) sur un arbre,
remplacez l'élément content
par un élément treeitem
Le dernier élément que vous pouvez ajouter à l'intérieur d'une règle est l'élément
bindings
.
À l'intérieur de celui-ci, vous pouvez mettre un ou plusieurs élément
binding
.
Un lien dans une règle a la même syntaxe qu'un triplet et remplit quasiment la même fonction.
Par exemple, dans l'exemple météo précédent, on peut ajouter le lien suivant :
<bindings>
<binding subject="?city"
predicate="http://www.xulplanet.com/rdf/weather#temperature"
object="?temp"/>
</bindings>
Le lien va prendre la ressource "température" de chaque ville et l'attribuer à la variable temp
.
C'est tout à fait similaire à ce qu'un triplet accomplit.
La différence se situe dans le fait qu'un lien n'est pas examiné lorsque quand les conditions sont vérifiées.
Cela veut dire que chaque ville doit avoir un nom et une prédiction météo associée pour être affichée,
mais cela n'a aucune importance si elle n'a pas de température.
Cependant, si elle en a une, la valeur sera attribuée à la variable temp
afin qu'elle soit utilisée
dans une action. Si une ville n'a pas de température, la variable temp
sera une chaîne de caractère vide.
Par la suite, nous verrons comment ajouter des gestionnaires d'évènements dans les éléments XUL.