Format Rdf/Introduction

RDF par l'exemple

Courte définition

RDF, c'est un moyen d'exprimer des relations. Ces relations sont décrites sous forme de graphe. Chaque nœud du graphe est une ressource ou une valeur. Et chaque nœud est relié à un autre par un arc "nommé".

Exemple :

 urn:users:456  -> http://xulfr.org/users#name -> laurent

Ce qui donne, graphiquement :

http://xulfr.org/images/wiki/rdf/rdf_simple.png

Nous avons ici deux noeuds, "urn:users:456" et "laurent", reliés par un arc nommé "http://xulfr.org/users#name".

En d'autres termes :

  • urn:users:456 est ce qu'on appelle une ressource, ou encore sujet, source
  • http://xulfr.org/users#name est ce qu'on appelle un prédicat ou encore une propriété
  • laurent est ce qu'on appelle une valeur ou encore un objet, une cible (target)

Sachant que la cible peut être un littéral comme ici, ou une autre ressource. Toute ressource possède un identifiant sous forme d'uri (url ou urn). Si une ressource ne possède pas explicitement un identifiant, le logiciel qui lira le RDF en attribuera un implicitement. Les prédicats sont également identifiés par une url.

Légende dans les schémas qui suivent :

http://xulfr.org/images/wiki/rdf/rdf_legende.png

Attention : les urls que l'on utilise dans un fichier RDF ne sont pas forcément des urls web existantes. C'est juste un moyen d'avoir un identifiant unique pour chaque ressource et prédicat.

un exemple concret

En fait, on peut faire une analogie entre les bases de données relationnelles SQL, et RDF. On peut décrire le contenu d'une base de donnée sous forme RDF (bien qu'avec RDF, on puisse aller plus loin que ce que permet un SGBD en terme de relations ).

Voyons par exemple comme exprimer le contenu d'une table SQL "news". Imaginons que cette table contienne les champs "id_news", "titre", "texte", "date". En RDF, les noms des champs vont être les prédicats. Leurs valeurs de ces champs seront les valeurs associées à ces prédicats. Et chaque enregistrement constituera alors une ressource.

Voici trois news :

 id_news   titre   texte   date 
 1   foo   blablafoo   01/01/2006 
 2   bar   blablabar   01/01/2006 
 3   baz   blablabaz   02/01/2006 

Créer une liste de ressource

Comme toute table sql, nous avons à faire à une liste de données. Nous allons donc créer une ressource que l'on appellera "urn:listenews" (on pourrait aussi utiliser une url, par exemple http://xulfr.org/ressources/listenews). Cette ressource contiendra une liste d'autres ressources qui elles mêmes contiendront les informations de chaque news.

Nous utilisons la balise RDF <Bag> pour exprimer le fait que l'on a à faire à une liste non ordonnée. Pour indiquer une liste ordonnée, on aurait utilisé <Seq>. L'attribut RDF:about permet d'indiquer l'url de la ressource.

Voici donc cette première ressource :

 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

    <Bag RDF:about="urn:listenews">

    </Bag>
 </RDF>

On va maintenant dire que cette ressource "urn:listenews", contient les ressources correspondantes à chaque news. On donnera alors à chacune de ces ressources une url, dans laquelle on utilisera l'id de la news : "urn:news:id_de_la_news". Cela permet d'avoir des urls uniques et cohérentes pour chaque news.

On liste le contenu d'un <Bag> au moyen de la balise <li>. En fait, chaque <li> est un prédicat (de nom li). Et la valeur de ces prédicats sera une url de ressource (en l'occurence, l'url d'une ressource de news), que l'on indique au moyen de l'attribut RDF:resource.

 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

    <Bag RDF:about="urn:listenews">
        <li RDF:resource="urn:news:1"/>
        <li RDF:resource="urn:news:2"/>
        <li RDF:resource="urn:news:3"/>
    </Bag>
 </RDF>

On a ainsi créé le graph suivant :

http://xulfr.org/images/wiki/rdf/rdf_tuto1_1.png

Décrire une ressource

Maintenant, il faut décrire ce que contiennent les ressources urn:news:*. Pour cela on a la balise <Description> en RDF. On va en créer une pour chaque ressource news. On utilise encore l'attribut RDF:about pour indiquer à quel ressource la description est rattachée.

 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

    <Bag RDF:about="urn:listenews">
        <li RDF:resource="urn:news:1"/>
        <li RDF:resource="urn:news:2"/>
        <li RDF:resource="urn:news:3"/>
    </Bag>

    <Description RDF:about="urn:news:1"/>
    <Description RDF:about="urn:news:2"/>
    <Description RDF:about="urn:news:3"/>
 </RDF>

Malgré l'ajout de ces balises, notre graphe n'a toujours pas changé. On va maintenant remplir les descriptions. On va en fait indiquer les prédicats correspondant à chaque champs des enregistrements. On va utiliser le namespace http://xufr.org/ns/news# comme racine de leur url, que l'on déclare à la racine du document :

  <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:news="http://xufr.org/ns/news#">

Voici les descriptions complètes :

    <Description RDF:about="urn:news:1" news:id_news="1" news:titre="foo" news:texte="blablafoo" news:date="01/01/2006" />
    <Description RDF:about="urn:news:2" news:id_news="2" news:titre="bar" news:texte="blablabar" news:date="01/01/2006" />
    <Description RDF:about="urn:news:3" news:id_news="3" news:titre="baz" news:texte="blablabaz" news:date="02/01/2006" />

Ici on a utilisé des attributs, mais on peut aussi utiliser des éléments, cela revient strictement au même. Par exemple :

    <Description RDF:about="urn:news:1">
        <news:id_news>1</news:id_news>
        <news:titre>foo</news:titre>
        <news:texte>blablafoo</news:texte>
        <news:date>01/01/2006</news:date>
    </Description>

Notre contenu rdf complet est le suivant

  <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:news="http://xufr.org/ns/news#">

    <Bag RDF:about="urn:listenews">
        <li RDF:resource="urn:news:1"/>
        <li RDF:resource="urn:news:2"/>
        <li RDF:resource="urn:news:3"/>
    </Bag>

    <Description RDF:about="urn:news:1">
        <news:id_news>1</news:id_news>
        <news:titre>foo</news:titre>
        <news:texte>blablafoo</news:texte>
        <news:date>01/01/2006</news:date>
    </Description>
    <Description RDF:about="urn:news:2" news:id="2" news:titre="bar" news:texte="blablabar" news:date="01/01/2006" />
    <Description RDF:about="urn:news:3" news:id="3" news:titre="baz" news:texte="blablabaz" news:date="02/01/2006" />
 </RDF>

Ce qui correspond à ce graphe plus complet maintenant :

http://xulfr.org/images/wiki/rdf/rdf_tuto1_2.png

Ajouter des nouveaux types de ressources

Nous voulons maintenant classer les news dans des catégories. En SQL, nous aurions fait une table catégories, contenant les champs id_cat, et libelle.

 id_cat   libelle 
 1   "technologie" 
 2   "Mozilla" 

Et les enregistrements de la table news aurait un id_cat également (clé étrangère). Les descriptions de nos news deviendraient alors :

    <Description RDF:about="urn:news:1">
        <news:id_news>1</news:id_news>
        <news:id_cat>1</news:id_cat>
        <news:titre>foo</news:titre>
        <news:texte>blablafoo</news:texte>
        <news:date>01/01/2006</news:date>
    </Description>

http://xulfr.org/images/wiki/rdf/rdf_tuto1_3.png

Le problème ici, c'est que l'on a que l'id de la catégorie. Comment inclure alors le reste des informations contenant les catégories ? On pourrait faire ceci :

    <Description RDF:about="urn:news:1">
        <news:id_news>1</news:id_news>
        <news:id_cat>
            <Description>
                <cat:id_cat>1</cat:id_cat>
                <cat:libelle>technologie</cat:libelle>
            </Description>
        </news:id_cat>
        <news:titre>foo</news:titre>
        <news:texte>blablafoo</news:texte>
        <news:date>01/01/2006</news:date>
    </Description>

Sans oublier dans la racine du document de déclarer le namespace cat :

  <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:news="http://xufr.org/ns/news#"
    xmlns:cat="http://xufr.org/ns/categories#"
    >

http://xulfr.org/images/wiki/rdf/rdf_tuto1_4.png

On a ainsi modifié le prédicat news:id_cat : sa valeur n'est plus un littéral, mais une nouvelle ressource, que l'on a décrite grâce à la balise Description. Attention, faire ceci n'a aucun sens en RDF :

        <news:id_cat>
            <cat:id_cat>1</cat:id_cat>
            <cat:libelle>technologie</cat:libelle>
        </news:id_cat>

On a décrit des ressources catégories pour chaque news, mais on a toutefois un autre problème : si plusieurs news sont dans les mêmes catégories, on va avoir des informations redondantes (ici le libelle). Notre graphe ne va pas être "optimisé". Utilisons au mieux alors le RDF, et faisons une sorte de jointure comme on fait en SQL :

1) on va créer une ressource pour chaque catégorie, que l'on va décrire dans une balise <Description> comme on l'a fait précédemment, mais cette fois-ci, on va les déclarer en dehors des ressources news et on va les référencer avec une url de type "urn:categorie:id_de_la_categorie" :

    <Description RDF:about="urn:categorie:1" cat:id_cat="1" cat:libelle="technologie" />
    <Description RDF:about="urn:categorie:2" cat:id_cat="2" cat:libelle="Mozilla" />

2) Et dans le prédicat "news:id_cat", on lui indique que sa valeur est l'une de ces ressources, grâce à l'attribut RDF:resource :

    <Description RDF:about="urn:news:1">
        <news:id_news>1</news:id_news>
        <news:id_cat RDF:resource="urn:categorie:1" />
        <news:titre>foo</news:titre>
        <news:texte>blablafoo</news:texte>
        <news:date>01/01/2006</news:date>
    </Description>

Cela donne :

http://xulfr.org/images/wiki/rdf/rdf_tuto1_5.png

Vous remarquerez que le graphe n'a pas beaucoup changé, concernant la ressource urn:news:1.

Le fichier rdf entier :

 <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:news="http://xufr.org/ns/news#"
    xmlns:cat="http://xufr.org/ns/categories#"
    >

    <Bag RDF:about="urn:listenews">
        <li RDF:resource="urn:news:1"/>
        <li RDF:resource="urn:news:2"/>
        <li RDF:resource="urn:news:3"/>
    </Bag>

    <Description RDF:about="urn:news:1">
        <news:id_news>1</news:id_news>
        <news:id_cat RDF:resource="urn:categorie:1" />
        <news:titre>foo</news:titre>
        <news:texte>blablafoo</news:texte>
        <news:date>01/01/2006</news:date>
    </Description>
    <Description RDF:about="urn:news:2" news:id="2" news:titre="bar" news:texte="blablabar" news:date="01/01/2006">
        <news:id_cat RDF:resource="urn:categorie:1" />
    </Description>
    <Description RDF:about="urn:news:3" news:id="3" news:titre="baz" news:texte="blablabaz" news:date="02/01/2006">
        <news:id_cat RDF:resource="urn:categorie:2" />
    </Description>

    <Description RDF:about="urn:categorie:1" cat:id_cat="1" cat:libelle="technologie" />
    <Description RDF:about="urn:categorie:2" cat:id_cat="2" cat:libelle="Mozilla" />
  </RDF>

Et si on veut lister les catégories ?

Pour avoir une liste de toutes les ressources catégories, il suffit de créer une nouvelle liste, comme on l'a fait pour avoir la liste des news.

    <Bag RDF:about="urn:listecategories">
        <li RDF:resource="urn:categorie:1"/>
        <li RDF:resource="urn:categorie:2"/>
        <li RDF:resource="urn:categorie:3"/>
    </Bag>

http://xulfr.org/images/wiki/rdf/rdf_tuto1_6.png

Conclusion

On remarque donc qu'un fichier RDF "basique", ce n'est rien d'autre que :

  1. des descriptions de ressources (ou, par analogie à SQL, d'enregistrements) via une balise Description ou Bag (et Seq ou Alt mais que l'on a pas vu)
  2. chaque ressource est identifiée par une url, via l'attribute RDF:about (ce qui correspond aux clés primaires SQL)
  3. chaque ressource contient une série de prédicats qui la décrit (les champs des tables SQL)
  4. la valeur des prédicats peuvent être des littéraux (valeurs simple), ou un lien vers une autre ressource via l'attribut RDF:resource (clé étrangère en SQL).

Dernière modification le février 5, 2007 10:46 .


Le contenu de cette page est disponible selon certaines conditions de réutilisation. Lire aussi la page des informations légales.

Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™ sont des marques de la fondation Mozilla.