<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE webpage PUBLIC "-//Norman Walsh//DTD Website V2.1b1//EN" "../../../dtd/website.dtd" [
  <!ENTITY application SYSTEM "applications.xml" NDATA XML>
  <!ENTITY base SYSTEM "bases.xml" NDATA XML>
  <!ENTITY entrepot SYSTEM "entrepots.xml" NDATA XML>
  <!ENTITY index SYSTEM "../index.xml" NDATA XML>
  <!ENTITY installation SYSTEM "../installer.xml" NDATA XML>
  <!ENTITY multilinguisme SYSTEM "multilinguisme.xml" NDATA XML>
  <!ENTITY serveur SYSTEM "serveur.xml" NDATA XML>
  <!ENTITY simplesearch SYSTEM "../reference/actions_requetes.xml" NDATA XML>
]>

<webpage id="debuter"> 

  <head>
	 <title>Bien débuter avec SDX-2</title>
	 <titleabbrev>Débuter</titleabbrev>
	 <author>
		<firstname> 
		  <ulink url="mailto:pierrick.brihaye@culture.gouv.fr">Pierrick</ulink> </firstname>
		<surname> 
		  <ulink url="mailto:pierrick.brihaye@culture.gouv.fr">Brihaye</ulink> </surname>
		<affiliation>
		  <orgname>Service Régional de l'<ulink url="http://www.culture.fr/culture/inventai/presenta/invent.htm">Inventaire</ulink>, 
			 <ulink url="http://www.culture.gouv.fr/bretagne/">DRAC Bretagne</ulink>, 
			 <ulink url="http://www.culture.fr">MCC</ulink> </orgname> 
		</affiliation>
	 </author>
	 <revhistory>
		<revision>
		  <revnumber>1.0</revnumber> 
		  <date>2003-06-03</date> 
		</revision>
	 </revhistory>
  </head>

  <para>Ca y est ! Vous venez d'<olink targetdocent="installation">installer</olink> SDX-2 avec succès : vous avez pu prendre contact avec les possibilités d'administration du 
	 <olink targetdocent="serveur">serveur</olink> et accédé à l'<olink targetdocent="application">application</olink> de démonstration. Vous y avez chargé des documents XML, peut-être même des documents HTML en provenance d'un système de fichiers local ou d'Internet, ce qui vous a donné une idée de la façon dont SDX indexait les documents. Ensuite, vous avez vu de quelle façon SDX pouvait restituer les documents à la suite d'une requête. Bref, vous avez compris les grandes lignes du fonctionnement de SDX. </para>
  <para>C'est décidé, vous allez monter une application, offrir un moteur de recherche permettant la diffusion de vos milliers de documents XML ou HTML sur la toile : votre chef sera content, vous allez être promu, vous pourrez négocier une augmentation en position de force, vous brillerez dans les salons, vos écrouelles vont miraculeusement disparaître si bien que vous allez pouvoir envisager des tas de conquêtes f/m... <emphasis role="bold">STOP !!!</emphasis> </para>
  <section> 
	 <title>Gardons la tête froide</title>
	 <para>Avant toute chose, reportez vous à la documentation sur les 
		<olink targetdocent="application">applications</olink> : elle donne des pistes pour résoudre les épineux problèmes de responsabilité éditoriale et de responsabilité informatique. Dans ce document, nous prendrons le parti que vous êtes <emphasis>à la fois</emphasis> l'éditeur et le responsable informatique. Ainsi, vous pourrez commencer à développer votre première application sans avoir à vous soucier du fait que vos documents puissent être diffusés ou pas, que votre serveur puisse assumer la montée en charge qui sied à un site attractif, de qui a les droits en écriture sur votre base de documents... De plus, votre pare-feu vous protège du monde sauvage des hackers si bien que vous pouvez sans appréhension ouvrir un serveur HTTP comme l'est un moteur de servlets. N'oubliez cependant <emphasis>jamais</emphasis> que vous aurez <emphasis>tôt ou tard</emphasis> à résoudre le
		déploiement de votre application sur un serveur de production.</para>
	 <para>Ensuite, vous devez réflechir au concept même de 
		<olink targetdocent="base">base</olink> SDX. A ce sujet il peut être intéressant de voir ou revoir ce que ce terme signifie.</para>
	 <orderedlist>
		<listitem>
		  <para>Au sens strict du terme, une <emphasis>base de données</emphasis> est un <emphasis>endroit où se trouvent des données</emphasis>. </para>
		  <para>La définition est simple, mais elle doit cependant être discutée. Doit-on considérer que :</para>
		  <orderedlist numeration="loweralpha">
			 <listitem>
				<para>la base de données s'accapare, grâce aux privilèges quasi-exclusifs qu'elle a sur eux, les fichiers informatiques sur disque et/ou en mémoire qui ne sont rien d'autre que la <emphasis>réalité physique</emphasis> des données,</para>
			 </listitem>
			 <listitem>
				<para>la base de données peut se contenter de <emphasis>référencer</emphasis> les données et de <emphasis>déléguer</emphasis> la gestion des fichiers à d'autres systèmes, éventuellement distants, répondant au critère ci-dessus défini ?</para>
			 </listitem>
		  </orderedlist>
		  <para>Quelle que soit la réponse, SDX <emphasis role="bold">est</emphasis> une base de données. En effet, il stocke les données dans des 
			 <olink targetdocent="entrepot">entrepôts</olink>. Certains stockent physiquement les données (<literal>FSRepository</literal>, <literal>JDBCRepository</literal>), d'autres non (<literal>URLRepository</literal>). Certes, on joue sur les mots : ce n'est pas <emphasis>SDX</emphasis> qui stocke les documents ou leurs références, ce sont des composants travaillant <emphasis>avec</emphasis> SDX : <literal>Lucene</literal>, <literal>HSQL</literal>, <literal>MySQL</literal>, <literal>Oracle</literal>, <literal>PostGreSQL</literal>... Soit !</para>
		</listitem>
		<listitem>
		  <para>Une autre approche du terme consiste à considérer une base de données comme un <emphasis>moyen</emphasis> de retrouver des données grâce à un langage d'interrogation, si possible accessible à un utilisateur humain. Le concept initial glisse ainsi d'une réalité physique à une réalité logique (d'ailleurs, qui se soucie encore aujourd'hui de la forme physique des fichiers sur lesquels travaille un SGDB à part un développeur de SGDB ?).</para>
		  <para>Dans ce contexte, SDX <emphasis role="bold">est encore</emphasis> une base de données.</para>
		</listitem>
	 </orderedlist>
	 <para>Tout ceci étant dit, pourquoi choisir SDX ? Si l'on veut stocker des documents XML, pourquoi ne pas se contenter de bases de données XML comme 
		<ulink url="http://xml.apache.org/xindice/">XIndice</ulink> ou 
		<ulink url="http://exist-db.org/">eXist</ulink> ? D'autant plus que celles-ci disposent d'un langage de requête standardisé, de cautions prestigieuses, de nombreux utilisateurs, d'une plus grande activité, d'un support technique plus performant...</para>
	 <para>La réponse est simple... sur le plan théorique : parce que, à l'inverse des autres bases de données XML, SDX <emphasis>fait une distinction</emphasis> entre  :</para>
	 <orderedlist>
		<listitem>
		  <para>la forme que les documents revêtent lorsqu'il sont stockés (ou référencés),</para>
		</listitem>
		<listitem>
		  <para>la forme que les documents revêtent lorsqu'ils sont interrogés.</para>
		</listitem>
	 </orderedlist>
	 <para>Qu'est-ce que c'est que ce charabia ?</para>
	 <para>Prenons deux exemples simples : si vous stockez la valeur <literal>John Doe</literal> dans le champ <literal>name</literal> d'un SGDB SQL, vous vous attendez à pouvoir y accéder via une requête <literal>SELECT name FROM a_table WHERE name = 'John Doe';</literal>. De même, si vous stockez <sgmltag>&lt;NAME&gt;John Doe&lt;/NAME&gt;</sgmltag> dans une base de données XML, vous vous attendez à pouvoir retrouver cet élément grâce à une requête de ce type : <literal>document(*)//NAME = 'John Doe'</literal>.</para>
	 <para>Le problème est précisément là : pour rechercher le <emphasis>contenu</emphasis> d'un document on doit interroger sa <emphasis>structure</emphasis> et donc... <emphasis role="bold">la connaître</emphasis> !</para>
	 <para>Bien sûr, si vous pouvez garantir que <emphasis>tous</emphasis> vos documents XML auront la même structure (c'est à dire qu'ils partagent une même grammaire), vous pouvez envisager de les déployer sur une base de données, XML... ou autre. Mais, êtes vous prêt à payer le prix de langages de requêtes complexes et, surtout, pouvez-vous exiger des utilisateurs qu'ils connaissent la grammaire de vos documents ? Pour prendre un exemple simple, une DTD HTML, pensez vous que les utilisateurs penseront à interroger <literal>title</literal> alors qu'ils veulent un <literal>titre</literal> ? Et croyez-vous qu'ils penseront à interroger également <literal>h1</literal>, <literal>h2</literal>, <literal>h3</literal>... qui sont également des titres ?</para>
	 <para>Si vous pensez que oui, rendez vous directement aux liens mentionnés ci-dessus. Si vous pensez que non, vous pouvez passer à la section suivante...</para>
  </section> 
  <section> 
	 <title>L'indexation dans SDX</title>
	 <para>Comme on vient de le voir, SDX stocke ou référence des documents XML : le concept est suffisament traditionnel pour pouvoir être immédiatement compris. En revanche, quelle est cette mystérieuse forme que revêtent les documents lorsqu'ils sont interrogés ?</para>
	 <para>Tout d'abord, cette forme a un nom, l'<emphasis>indexation</emphasis>. Ce concept, lui aussi traditionnel, est clair : on prend les <emphasis>valeurs</emphasis> contenues dans les documents et on les <emphasis>référence</emphasis>, ce qui permet une recherche rapide car on n'a pas à interroger les documents un par un pour voir si la valeur recherchée y est présente... dans le cas le plus favorable.</para>
	 <para>Ici encore, les SGDB sont responsables d'un glissement de sens. Un index est, chez eux, une liste de valeurs dont <emphasis>on pense</emphasis> qu'elles seront plus souvent interrogées que d'autres. Les SGDB sont donc éternellement en quête d'un compromis entre la sélectivité des index et leur taille. En effet, il serait contre-productif pour eux d'indexer l'intégralité de la base de données car l'interrogation des index prendrait, par définition, autant de temps que la consultation de chacun des documents. Certes, chaque SGDB y va de son optimiseur de requêtes, de son analyseur d'index, de son détecteur de requêtes longues, de son cache d'index... mais, fondamentalement, les index n'ont, pour eux, que vocation à être un <emphasis>résumé</emphasis> de la base de données.</para>
	 <para>Avec SDX, la définition d'un index est la même, mais la doctrine d'emploi en est radicalement différente de celle d'un SGDB :</para>
	 <orderedlist>
		<listitem>
		  <para>vous pouvez définir des <emphasis>jeux</emphasis> d'index. C'est selon moi, dans le vocabulaire SDX, la définition même d'une 
			 <olink targetdocent="base">base</olink>. Ainsi, vous pouvez définir une logique applicative qui travaillera sur tels ou tels index plutôt que sur l'ensemble d'entre eux ce qui, bien balancé, permet une optimisation des performances. La logique applicative doit donc être un critère important sinon déterminant dans la définition d'une 
			 <olink targetdocent="base">base</olink> au sein d'une 
			 <olink targetdocent="application">application</olink> SDX,</para>
		</listitem>
		<listitem>
		  <para>le contenu des index est sous <emphasis>votre</emphasis> responsabilité et SDX ne vous impose pratiquement pas de limites (longueur, occurences...),</para>
		</listitem>
		<listitem>
		  <para>il n'est pas mal vu d'avoir de gros index : il est prévisible que beaucoup de bases auront un index <literal>fulltext</literal>,</para>
		</listitem>
		<listitem>
		  <para>il est tout à fait concevable que vos index aient un contenu qui n'a aucune relation avec celui de vos documents : vous pouvez donc vous en servir pour stocker toutes sortes de métadonnées (date de chargement, responsable du document, état de complétude...) qui seront fournies par la logique applicative.</para>
		</listitem>
	 </orderedlist>
	 <para>En résumé : vous pouvez définir (ou ne pas définir) vos index comme vous l'entendez et vous pouvez définir leur contenu comme vous l'entendez. Par ailleurs, vous pouvez les <emphasis>typer</emphasis> mais, pour l'instant, seuls les index de type <literal>chaîne de caractère</literal> et de type <literal>date</literal> sont possibles.</para>
	 <section> 
		<title>De la théorie à la pratique</title>
		<para>Vous disposez de documents XML (ou HTML que SDX transformera en documents XML grâce à l'intégration native de 
		  <ulink url="http://lempinen.net/sami/jtidy/">JTidy</ulink> dans son architecture) et vous allez devoir les indexer. Quelle doit être votre réflexion pour que ces documents puissent être indexés dans SDX ?</para>
		<para>Dans la plupart des cas, c'est l'information <emphasis>sémantique</emphasis> qui guidera votre choix. En effet, les informations de structure n'ont souvent aucun intérêt pratique pour un utilisateur de base et, parfois, pour un utilisateur avancé. Vous devez donc dresser la liste des sémantiques que vous voulez rendre interrogeables et, vous ne pourrez pas y passer sauf à développer des fonctions ad hoc, chercher les moyens de retrouver les sémantiques choisies dans vos différents types de documents.</para>
		<para> Ainsi, si vous disposez des documents suivants :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE chapter PUBLIC "-//Norman Walsh//DTD DocBk XML V1.3//EN"
  "n:/share/sgml/Norman_Walsh/db31xml/db3xml.dtd">
<chapter>
  <title>Premier chapitre</title>
  <para>
    La première fois que j'ai vu <firstname>Nikita</firstname>...
  </para>
</chapter>
	]]></programlisting> 
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<movie>
  <title>Nikita</title>
  <director>Luc Besson</director>
  <type>Thriller</type>
  <date>1990</date>
  <roles>
    <role>
      <character>Nikita</character>
      <actor>Anne Parillaud</actor>    
    </role>    
  </roles> 
</movie>
	]]></programlisting> 
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<rapport>
  <de>4eme bureau</de>
  <a>2eme bureau</a>
  <resume>Activités de <nom>Nikita</nom></resume>
  <detail>A récemment été vue à <lieu>Venise</lieu> où on la soupçonne d'avoir...</detail>
</rapport>
	]]></programlisting> 
		<para>... vous avez matière à indexer, et donc à rendre cherchable, des informations concernant des noms de personnes (mais n'oubliez pas de déclarer votre fichier à la 
		  <ulink url="http://www.cnil.fr/">CNIL</ulink>).</para>
		<para>Pour ce faire, une solution évidente s'impose : <emphasis role="bold">XSLT</emphasis>. Profitons-en pour rappeler que SDX réclame une <emphasis>bonne connaissance</emphasis> de ce langage. C'est précisément le parti qu'a choisi SDX pour générer les valeurs d'index : il attend une <emphasis>transformation</emphasis> des documents XML d'origine pour parvenir à un document transformé répondant à la DTD suivante :</para>
		<programlisting><![CDATA[
<!ELEMENT sdx:document (sdx:field | sdx:attachedDocument)*>
<!ATTLIST sdx:document
	id CDATA #REQUIRED
>
<!ELEMENT sdx:field (#PCDATA)>
<!ATTLIST sdx:document
	name CDATA #REQUIRED
>
<!ELEMENT sdx:attacheddocument (EMPTY)>
<!ATTLIST sdx:attacheddocument
	id CDATA #REQUIRED
	url CDATA #REQUIRED
	mimetype CDATA #REQUIRED
>
]]></programlisting> 
		<para>Votre document d'indexation devra donc comporter les éléments suivants </para>
		<orderedlist>
		  <listitem>
			 <para>Un élément racine <sgmltag>&lt;sdx:document&gt;</sgmltag> contenant un attribut obligatoire <sgmltag>id</sgmltag>. Cet attribut affecte au document indexé un identifiant unique dans la base ; nous en reparlerons.</para>
		  </listitem>
		  <listitem>
			 <para>D'éventuels éléments <sgmltag>&lt;sdx:field&gt;</sgmltag> dont le contenu sera précisément le contenu des index. A première vue, il est assez paradoxal qu'un index soit défini par un élément nommé <emphasis>field</emphasis>. Cela s'explique pour des raisons historiques : les index de SDX étaient, et sont encore, transcrits dans des objets 
				<ulink url="http://jakarta.apache.org/lucene/docs/api/org/apache/lucene/document/Field.html">Field</ulink> de 
				<ulink url="http://jakarta.apache.org/lucene/docs/index.html">Lucene</ulink>.</para>
			 <para>L'attribut obligatoire <sgmltag>name</sgmltag> indique le <emphasis>nom</emphasis> de l'index ; nous en reparlerons également. <emphasis>Important :</emphasis> les index dont le nom commence par <literal>sdx</literal> sont réservés à SDX.</para>
			 <para>D'ores et déjà, il est important de préciser qu'un index ayant un nom déterminé peut avoir <emphasis role="bold">plusieurs occurences</emphasis> dans le même document d'indexation, ce qui revient à dire qu'un même index SDX peut recevoir plusieurs parties d'un même document.</para>
			 <para>Certes, ces éléments sont facultatifs... mais si vous ne créez pas de contenu pour vos index, votre base ne sera pas interrogeable.</para>
		  </listitem>
		  <listitem>
			 <para>D'éventuels éléments <sgmltag>&lt;sdx:attachedDocument&gt;</sgmltag> qui permettent de définir une liste de documents qui doivent être chargés en même temps que le document XML et qui <emphasis>ne sont pas indexés</emphasis>. Ces documents seront considérés comme propriété du document XML et seront détruits si le document "maître" venait à l'être... à moins que le document attaché n'ait été mis à disposition d'autres documents "maîtres" par la suite.</para>
			 <para>L'attribut obligatoire <sgmltag>id</sgmltag> indique l'identifiant unique du document attaché dans la base. C'est grâce à cette <sgmltag>id</sgmltag> que les documents attachés peuvent être éventuellement partagés : il suffit de la réutiliser.</para>
			 <para>L'attribut obligatoire <sgmltag>url</sgmltag> indique l'adresse du document attaché, adresse qui sera utilisée par SDX pour le chargement du document attaché. Le cas échéant, ce peut être une adresse relative <emphasis>au document maître</emphasis> (mais veillez à ce qu'elle soit accessible au serveur SDX).</para>
			 <para>L'attribut obligatoire <sgmltag>mimetype</sgmltag> indique le type MIME du document attaché (<literal>image/jpeg</literal>, <literal>video/mpeg</literal>...), ce qui permettra aux API URL de SDX de mettre ce document attaché à la disposition du navigateur ou d'autres applications respectant le protocole HTTP.</para>
		  </listitem>
		</orderedlist>
	 </section> 
	 <section> 
		<title>Et maintenant, un peu de pratique</title>
		<para>Vous disposez maintenant de tous les éléments pour créer un document d'indexation SDX. Vous pouvez, au choix, rédiger une ou plusieurs (mais une seule est préférable pour des raisons dont nous reparlerons : si <emphasis>vraiment</emphasis> vous ne pouvez résoudre votre problème qu'à l'aide de plusieurs XSL, considérez la définition de plusieurs 
		  <olink targetdocent="base">bases</olink>) XSL qui seront à même de générer un document d'indexation à partir de <emphasis>vos</emphasis> documents XML. Dans l'exemple suivant, nous allons essayer de réaliser une feuille qui sera capable d'indexer, dans un index nommé <literal>personne</literal>, les noms contenus dans les documents montrés ci-dessus :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ne pas oublier le namespace SDX -->
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<!-- un paramètre recevant une valeur pour l'id du document --> 
	<xsl:param name="doc_id">xxx</xsl:param>
	<xsl:template match="/">
		<!-- soyons prudent : ne traitons que les documents que nous connaissons -->
		<xsl:apply-templates select="chapter"/>
		<xsl:apply-templates select="movie"/>
		<xsl:apply-templates select="rapport"/>
	</xsl:template>
	<xsl:template match="chapter">
		<!-- on définit un document avec l'id définie en paramètre -->
		<sdx:document id="{$doc_id}">
			<sdx:field name="personne">
				<xsl:value-of select="//firstname"/>
			</sdx:field>
		</sdx:document>
	</xsl:template>
	<xsl:template match="movie">
		<!-- on définit un document avec l'id définie en paramètre -->		
		<sdx:document id="{$doc_id}">
			<xsl:for-each select="//director | //character | //actor">
				<sdx:field name="personne">
					<xsl:value-of select="."/>
				</sdx:field>
			</xsl:for-each>
		</sdx:document>
	</xsl:template>
	<xsl:template match="rapport">
		<!-- on définit un document avec l'id définie en paramètre -->
		<sdx:document id="{$doc_id}">
			<sdx:field name="personne">
				<xsl:value-of select="de"/>
			</sdx:field>
			<sdx:field name="personne">
				<xsl:value-of select="a"/>
			</sdx:field>
			<sdx:field name="personne">
				<xsl:value-of select="resume/nom"/>
			</sdx:field>						
		</sdx:document>
	</xsl:template>
</xsl:stylesheet>			
]]></programlisting> 
		<para>Cette transformation produit les résultats suivants :</para>
		<orderedlist>
		  <listitem>
			 <programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:field name="personne">Nikita</sdx:field>
</sdx:document>
]]></programlisting> 
		  </listitem>
		  <listitem>
			 <programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:field name="personne">Luc Besson</sdx:field>
	<sdx:field name="personne">Nikita</sdx:field>
	<sdx:field name="personne">Anne Parillaud</sdx:field>
</sdx:document>
]]></programlisting> 
		  </listitem>
		  <listitem>
			 <programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:field name="personne">4eme bureau</sdx:field>
	<sdx:field name="personne">2eme bureau</sdx:field>
	<sdx:field name="personne">Nikita</sdx:field>
</sdx:document>
]]></programlisting> 
		  </listitem>
		</orderedlist>
		<para>Facile, non ? A vous de jouer désormais. Lorsque votre ou vos XSL seront prêtes et que <emphasis>tous</emphasis> vos documents XML vous donneront les résultats escomptés, nous pourrons passer à l'étape suivante. Si d'ores et déjà vos documents possèdent en leur sein un identifiant unique, ou que vous pouvez rendre unique (par une concaténation par exemple), n'hésitez pas à alimenter l'attribut <sgmltag>id</sgmltag> de <sgmltag>&lt;sdx:document/&gt;</sgmltag> avec une valeur moins arbitraire que celle de la XSL ci-dessus.</para>
	 </section> 
	 <section> 
		<title>Bonus : l'indexation plein-texte</title>
		<para>En guise de cadeau, voici une XSL permettant d'indexer l'intégralité du contenu des éléments d'un document XML dans un index nommé <literal>contenu</literal> :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>					
<!-- ne pas oublier le namespace SDX -->
<xsl:stylesheet version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<xsl:template match="/">
		<sdx:document id="xxx">
			<sdx:field name="contenu">
				<!-- 
				la hiérarchie est passée en revue 
				sous le contrôle du mode "fulltext"
				-->
				<xsl:apply-templates mode="fulltext"/>
			</sdx:field>
		</sdx:document>
	</xsl:template>
	<!-- un modèle générique pour tous les éléments -->
	<xsl:template match="*" mode="fulltext">
		<!-- 
		un appel, éventuellement récursif, 
		sur le noeud texte 
		et/ou les éléments contenus 
		-->
		<xsl:apply-templates select="*|text()" mode="fulltext"/>
	</xsl:template>
	<!-- traitement des noeuds texte -->
	<xsl:template match="text()" mode="fulltext">
		<xsl:value-of select="normalize-space(.)"/>
		<!-- on ajoute une espace entre les contenus des différents noeuds -->
		<xsl:if test="normalize-space(.) !=''">
			<xsl:text>&#32;</xsl:text>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>
]]></programlisting> 
		<para>... ce qui donne (en ISO-8859-1) :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>					
<sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:field name="contenu">4eme bureau 2eme bureau Activités de Nikita 
	A récemment été vue à Venise où on la soupçonne d'avoir... </sdx:field>
</sdx:document>
]]></programlisting> 
		<para>Ne vous inquiétez pas de cette agglutination de mots qui peut être très longue. Nous verrons sous peu comment SDX les gère. Considérez pour l'instant que cette transformation est équivalente à ce document d'indexation :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>					
<sdx:document id="xxx" xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:field name="contenu">4eme</sdx:field>
	<sdx:field name="contenu">bureau</sdx:field>
	<sdx:field name="contenu">2eme</sdx:field>
	<sdx:field name="contenu">bureau</sdx:field>
	<sdx:field name="contenu">Activités</sdx:field>
	<sdx:field name="contenu">de</sdx:field>
	<sdx:field name="contenu">Nikita</sdx:field>
	<sdx:field name="contenu">A</sdx:field>
	<sdx:field name="contenu">récemment</sdx:field>
	<sdx:field name="contenu">été</sdx:field>
	<sdx:field name="contenu">vue</sdx:field>
	<sdx:field name="contenu">à</sdx:field>
	<sdx:field name="contenu">Venise</sdx:field>
	<sdx:field name="contenu">où</sdx:field>
	<sdx:field name="contenu">on</sdx:field>
	<sdx:field name="contenu">la</sdx:field>
	<sdx:field name="contenu">soupçonne</sdx:field>
	<sdx:field name="contenu">d'avoir...</sdx:field>
</sdx:document>
]]></programlisting> 
	 </section> 
  </section> 
  <section> 
	 <title>Configuration d'une application et premier test</title>
	 <para>Vous voilà donc en mesure de disposer de documents d'indexation pour tous vos documents grâce à une XSL ad hoc. Le grand moment est arrivé : nous pouvons passer au déploiement. Rappelons au préalable la structure de répertoires de SDX apès son installation :</para>
	 <programlisting><![CDATA[
[TOMCAT_HOME]/webapps/sdx
                        +META-INF
                        +sdx
                        +sdxworld
                        +WEB-INF                        
]]></programlisting> 
	 <para>Le répertoire supérieur est le répertoire du <emphasis>contexte</emphasis> SDX. Les répertoires fils contiennent respectivement un répertoire pour les 
		<ulink url="http://java.sun.com/docs/books/tutorial/jar/basics/manifest.html">manifestes</ulink> (qui permettent par exemple l'authentification des composants logiciels), un répertoire pour l'application d'administration de SDX (qui contient également quelques ressources que nous aurons l'occasion d'utiliser), un répertoire pour une l'application exemple <literal>sdxworld</literal>et un répertoire de configuration du serveur SDX.</para>
	 <para>Vous pouvez maintenant créer un répertoire pour votre application. Appelons-le <filename>mon_app</filename> :</para>
	 <programlisting><![CDATA[
[TOMCAT_HOME]/webapps/sdx
                        +META-INF
                        +mon_app                        
                        +sdx
                        +sdxworld
                        +WEB-INF                        
]]></programlisting> 
	 <para> <filename>mon_app</filename> se déclare donc d'une façon strictement identique à celle des applications SDX "officielles". Etablissons maintenant une hiérarchie minimale dans ce répertoire :</para>
	 <programlisting><![CDATA[
[TOMCAT_HOME]/webapps/sdx
                        +META-INF
                        -mon_app                        
                         +conf
                         +xsl
                        +sdx
                        +sdxworld
                        +WEB-INF                        
]]></programlisting> 
	 <para>Les noms sont assez explicites : le premier répertoire recevra les fichiers de configuration de SDX, le second recevra les XSL à même de produire un résultat pour les clients, à savoir du code HTML.</para>
	 <para>Nous allons passer à la configuration proprement dite. Copiez au préalable le fichier <filename>sdxworld/sitemap.xmap</filename> dans le répertoire <filename>mon_app</filename> : nous verrons quelques-unes de ses fonctionnalités par la suite. Copiez ensuite votre XSL d'indexation dans le répertoire <filename>mon_app/conf</filename> sous le nom <filename>indexation.xsl</filename>. Créez dans le même répertoire un autre fichier, XML, que vous <emphasis>devez</emphasis> appeler <filename>application.xconf</filename>. Vous devez donc disposer de la hiérarchie suivante :</para>
	 <programlisting><![CDATA[
[TOMCAT_HOME]/webapps/sdx
                        +META-INF
                        -mon_app
                         -conf
                          application.xconf
                          indexation.xsl
                         +xsl
                         sitemap.xmap
                        +sdx
                        +sdxworld
                        +WEB-INF                        
]]></programlisting> 
	 <section> 
		<title>Rédaction du fichier de configuration de l'application</title>
		<para>Nous devons désormais alimenter le fichier <filename>application.xconf</filename> de notre application :</para>
		<orderedlist>
		  <listitem>
					<!-- dummy <para> element beaause of a formatting bug -->
			 <para> </para>
			 <programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<sdx:application 
	xmlns="http://www.culture.gouv.fr/ns/sdx/sdx"
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" 
	id="domaine.sdx.mon_app" xml:lang="fr-FR">
]]></programlisting> 
			 <para>L'élément racine, <sgmltag>&lt;sdx:application&gt;</sgmltag> comporte :</para>
			 <itemizedlist>
				<listitem>
				  <para>La définition obligatoire de <literal>namespaces</literal> SDX.</para>
				</listitem>
				<listitem>
				  <para>La définition obligatoire d'une <sgmltag>id</sgmltag> pour l'application. Voir la 
					 <olink targetdocent="application">documentation</olink> pour en savoir plus sur les règles de nommage qu'il convient d'adopter.</para>
				</listitem>
				<listitem>
				  <para>La définition obligatoire d'une <literal>locale</literal> <emphasis>par défaut</emphasis> pour l'application. Voir la 
					 <olink targetdocent="multilinguisme">documentation</olink> pour en savoir plus.</para>
				</listitem>
			 </itemizedlist>
		  </listitem>
		  <listitem>
			 <para>Ensuite, viennent normalement des informations sur les autorisations d'accès. Nous ne nous en soucierons pas pour l'instant et nous nous passerons de cette déclaration.</para>
		  </listitem>
		  <listitem>
			 <para>Ensuite, vient la définition de la base des utilisateurs qui est... une base SDX. Recopions la configuration par défaut qui devrait suffire dans la plupart des cas :</para>
			 <programlisting><![CDATA[
<sdx:userDocumentBase>
	<sdx:repositories>
		<sdx:repository id="users" type="FS" 
			baseDirectory="users/xml" 
			depth="0" extent="1000"/>
	</sdx:repositories>
	<sdx:fieldList xml:lang="fr-FR" variant="">
		<sdx:field name="name" type="field" brief="true"/>
		<sdx:field name="firstname" type="field" brief="true"/>
		<sdx:field name="lastname" type="field" brief="true"/>
		<sdx:field name="description" type="word"/>
		<sdx:field name="lang" type="field" brief="true"/>
		<sdx:field name="variant" type="field" brief="true"/>
		<sdx:field name="email" type="field" brief="true"/>
		<sdx:field name="content" type="word" default="true">
			<sdx:name xml:lang="fr-FR">Texte intégral</sdx:name>
		</sdx:field>
	</sdx:fieldList>
	<sdx:index>
		<sdx:pipeline>
			<sdx:transformation id="index" type="XSLT" 
				src="/sdx/resources/indexation/index-identity.xsl"/>
		</sdx:pipeline>
	</sdx:index>
</sdx:userDocumentBase>
]]></programlisting> 
			 <para>Etant donné que cette base d'utilisateurs est une base SDX, nous préférons commenter la structure de cet élément lors d'une phase suivante. Notons cependant que cette base n'a pas d'identifiant (attribut <sgmltag>id</sgmltag>).</para>
		  </listitem>
		  <listitem>
			 <para>Sujet connexe au précédent, nous définissons le groupe des administrateurs de la base et, dans ce groupe, nous définissons un membre ainsi que son éventuel mot de passe :</para>
			 <programlisting><![CDATA[
<sdx:admin groupId="admins" userId="admin" userPassword="secret"/>
]]></programlisting> 
		  </listitem>
		  <listitem>
			 <para>Entrons maintenant dans le vif du sujet en définissant <emphasis>notre</emphasis> base :</para>
			 <itemizedlist>
				<listitem>
							<!-- dummy <para> element beaause of a formatting bug -->
				  <para> </para>
				  <programlisting><![CDATA[
<sdx:documentBases>
	<sdx:documentBase id="ma_base" type="lucene" 
		default="true" keepOriginalDocuments="true">
]]></programlisting> 
				  <para>Le premier élément rappelle que SDX est multibase ; on peut donc définir autant de bases que l'on veut.</para>
				  <para>Le second élément définit la base proprement dite : l'<sgmltag>id</sgmltag> doit être unique dans l'application, le <sgmltag>type</sgmltag> est pour l'instant limité à <literal>lucene</literal>, l'attribut <sgmltag>default</sgmltag> est utile lorsque l'application est multibase et l'attribut <sgmltag>keepOriginalDocuments</sgmltag> définit le comportement à adopter lors du stockage des documents dans la base : nous en reparlerons.</para>
				</listitem>
				<listitem>
				  <para>Vient ensuite la définition du parseur de requêtes qui sera utilisé pour les 
					 <olink targetdocent="simplesearch" localinfo="sdx_simplequery">requêtes simples</olink>. Nous allons utiliser le parseur par défaut de SDX qui est le 
					 <ulink url="http://lucene.sourceforge.net/doc/api/com/lucene/queryParser/QueryParser.html">parseur</ulink> de Lucene.</para>
				  <programlisting><![CDATA[
<sdx:queryParser class="fr.gouv.culture.sdx.search.lucene.queryparser.DefaultQueryParser"/>
]]></programlisting> 
				</listitem>
				<listitem>
				  <para>Définissons ensuite deux 
					 <olink targetdocent="entrepot">entrepôts</olink>, le premier <emphasis>stockera</emphasis> les documents dans le système de fichiers de SDX, le second <emphasis>référencera</emphasis> les documents grâce à leur URL.</para>
				  <programlisting><![CDATA[
<sdx:repositories>
	<sdx:repository type="FS" id="stockage" 
		baseDirectory="entrepots/documents"
		depth="0" extent="100" default="true"/>
	<sdx:repository id="references" type="URL"/>
</sdx:repositories>
]]></programlisting> 
				  <para> <emphasis>Rappel :</emphasis> rappelons que le protocole <emphasis>file://</emphasis> est un protocole valide pour une URL et que, par conséquent, il est possible de <emphasis>référencer</emphasis> des fichiers qui sont sur le système de fichiers local sans pour autant appartenir au système de fichiers que le moteur de Servlets met à la disposition de SDX : nous en reparlerons.</para>
				</listitem>
				<listitem>
				  <para>Vient ensuite la liste d'index. Nous en définirons deux, l'un s'appelant <literal>contenu</literal>, sensé recevoir notre indexation plein-texte, l'autre s'appelant <literal>personne</literal>. Nous fournissons également des traductions de ces concepts dans quelques langues afin de pouvoir offrir des traductions aux utilisateurs le moment venu.</para>
				  <programlisting><![CDATA[						
<sdx:fieldList xml:lang="fr-FR" variant="" 
	analyzerConf="/sdx/resources/conf/analysis/fr.xml">	
	<sdx:field name="contenu" type="word" default="true">
		<sdx:name xml:lang="fr">Mots</sdx:name>
		<sdx:name xml:lang="en">Words</sdx:name>
		<sdx:name xml:lang="ge">W_rter</sdx:name>
		<sdx:name xml:lang="ar">الكلمات</sdx:name>
		<sdx:name xml:lang="br">Gerioù</sdx:name>
		<sdx:name xml:lang="eu">Hitzak</sdx:name>
	</sdx:field>	
	<sdx:field name="personne" type="field" brief="true">
		<sdx:name xml:lang="fr">Personnes</sdx:name>
		<sdx:name xml:lang="en">Persons</sdx:name>
		<sdx:name xml:lang="ge">Personnen</sdx:name>
		<sdx:name xml:lang="ar">الأشخاص</sdx:name>
		<sdx:name xml:lang="br">Tud</sdx:name>
		<sdx:name xml:lang="eu">Pertsonak</sdx:name>
	</sdx:field>
</sdx:fieldList>
]]></programlisting> 
				  <para>La définition de la liste fait encore une fois appel à une définition de <literal>locale</literal> <emphasis>par défaut</emphasis>. De plus, elle associe un fichier de configuration pour l'analyseur d'index ; ce fichier contient donc une liste-type de mots vides de la <emphasis>langue française</emphasis>. Libre à vous de faire pointer la configuration de l'analyseur vers votre propre fichier.</para>
				  <para>Les définitions d'index comportent un attribut obligatoire <sgmltag>name</sgmltag> qui correspond à l'attribut <sgmltag>name</sgmltag> de chacun des éléments <sgmltag>&lt;sdx:field&gt;</sgmltag> de vos transformations d'indexation. Si votre transformation génére des attributs <sgmltag>name</sgmltag> qui ne figurent pas dans cette liste, SDX vous renverra une erreur. En revanche, il est tout à fait possible que certains index puissent n'être utilisés que plus tard, lorsque votre transformation d'indexation sera capable de générer du contenu pour eux.</para>
				  <para>L'attribut <sgmltag>type</sgmltag> sert à définir la façon dont l'index sera constitué :</para>
				  <itemizedlist>
					 <listitem>
						<para>Un index de type <literal>word</literal> stockera des <emphasis>mots</emphasis> qui seront au préalable analysés (on vient de définir l'analyseur par défaut). Par ce terme, on entend par exemple que les mots vides ne seront pas indexés, les majuscules seront tranformées en minuscules, les accents seront supprimés...</para>
					 </listitem>
					 <listitem>
						<para>Un index de type <literal>field</literal> verra son contenu stocké <emphasis>tel quel</emphasis>. Les recherches devront donc se faire en tenant compte des majsucules, des minuscules, des espaces...</para>
					 </listitem>
					 <listitem>
						<para>Un index de type <literal>date</literal> stockera une <emphasis>date</emphasis> dans un format interne à SDX. Ainsi, quel que soit le format de date fourni, SDX sera en principe capable d'assurer la cohérence des contenus et de donc de garantir des requêtes homogènes sur ce type d'index.</para>
					 </listitem>
				  </itemizedlist>
				  <para>L'attribut <sgmltag>brief</sgmltag> indique que le contenu de l'index sera retourné dans les résultats d'une requête : on verra l'usage qu'on peut en faire mais, d'ores et déjà, on peut dire que cela sert essentiellement à :</para>
				  <itemizedlist>
					 <listitem>
						<para>afficher des <emphasis>listes de résultats</emphasis>,</para>
					 </listitem>
					 <listitem>
						<para>donner les moyens à SDX de <emphasis>trier les résultats</emphasis>.</para>
					 </listitem>
				  </itemizedlist>
				</listitem>
				<listitem>
				  <programlisting><![CDATA[
<sdx:index>
	<sdx:pipeline>
		<sdx:transformation id="mon_indexation" 
		type="XSLT" src="indexation.xsl"/>
	</sdx:pipeline>
</sdx:index>
]]></programlisting> 
				  <para>Ce contenu concerne évidemment l'indexation mais il doit être noté que cela concerne l'indexation <emphasis>par défaut</emphasis> (car il est possible de définir des transformations d'indexation <emphasis>dynamiques</emphasis>). SDX utilise un 
					 <ulink url="http://xml.apache.org/cocoon/userdocs/concepts/">pipeline</ulink> Cocoon, ce qui permet éventuellement d'opérer la transformation d'indexation en plusieurs phases pour, au final, parvenir à un document d'indexation tel qu'il est attendu par SDX. Les adresses sont relatives au <emphasis>répertoire de configuration de l'application</emphasis>.</para>
				</listitem>
			 </itemizedlist>
		  </listitem>
		  <listitem>
			 <para>Fermons les éléments ouverts :</para>
			 <programlisting><![CDATA[
		</sdx:documentBase>
	</sdx:documentBases>
</sdx:application>
]]></programlisting> 
		  </listitem>
		</orderedlist>
		<para>Récapitulons le contenu de notre fichier <filename>application.xconf</filename> :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<sdx:application 
	xmlns="http://www.culture.gouv.fr/ns/sdx/sdx" 
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" 
	id="domaine.sdx.mon_app" xml:lang="fr-FR">
	<sdx:userDocumentBase>
		<sdx:repositories>
			<sdx:repository id="users" type="FS" 
			baseDirectory="users/xml" 
			depth="0" extent="1000"/>
		</sdx:repositories>
		<sdx:fieldList xml:lang="fr-FR" variant="">
			<sdx:field name="name" type="field" brief="true"/>
			<sdx:field name="firstname" type="field" brief="true"/>
			<sdx:field name="lastname" type="field" brief="true"/>
			<sdx:field name="description" type="word"/>
			<sdx:field name="lang" type="field" brief="true"/>
			<sdx:field name="variant" type="field" brief="true"/>
			<sdx:field name="email" type="field" brief="true"/>
			<sdx:field name="content" type="word" default="true">
				<sdx:name xml:lang="fr-FR">Texte intégral</sdx:name>
			</sdx:field>
		</sdx:fieldList>
		<sdx:index>
			<sdx:pipeline>
				<sdx:transformation id="index" type="XSLT" 
				src="/sdx/resources/indexation/index-identity.xsl"/>
			</sdx:pipeline>
		</sdx:index>
	</sdx:userDocumentBase>
	<sdx:admin groupId="admins" userId="admin" userPassword="secret"/>
	<sdx:documentBases>
		<sdx:documentBase id="ma_base" type="lucene" 
		default="true" keepOriginalDocuments="true">
			<sdx:queryParser 
			class="fr.gouv.culture.sdx.search.lucene.queryparser.DefaultQueryParser"/>
			<sdx:repositories>
				<sdx:repository type="FS" id="stockage" 
				baseDirectory="entrepots/documents" 
				depth="0" extent="100" default="true"/>
				<sdx:repository id="references" type="URL"/>
			</sdx:repositories>
			<sdx:fieldList xml:lang="fr-FR" variant="" 
			analyzerConf="/sdx/resources/conf/analysis/fr.xml">
				<sdx:field name="contenu" type="word" default="true">
					<sdx:name xml:lang="fr">Mots</sdx:name>
					<sdx:name xml:lang="en">Words</sdx:name>
					<sdx:name xml:lang="ge">W_rter</sdx:name>
					<sdx:name xml:lang="ar">الكلمات</sdx:name>
					<sdx:name xml:lang="br">Gerioù</sdx:name>
					<sdx:name xml:lang="eu">Hitzak</sdx:name>
				</sdx:field>
				<sdx:field name="personne" type="field" brief="true">
					<sdx:name xml:lang="fr">Personnes</sdx:name>
					<sdx:name xml:lang="en">Persons</sdx:name>
					<sdx:name xml:lang="ge">Personnen</sdx:name>
					<sdx:name xml:lang="ar">الأشخاص</sdx:name>
					<sdx:name xml:lang="br">Tud</sdx:name>
					<sdx:name xml:lang="eu">Pertsonak</sdx:name>
				</sdx:field>
			</sdx:fieldList>
			<sdx:index>
				<sdx:pipeline>
					<sdx:transformation id="mon_indexation" 
					type="XSLT" src="indexation.xsl"/>
				</sdx:pipeline>
			</sdx:index>
		</sdx:documentBase>
	</sdx:documentBases>
</sdx:application>
]]></programlisting> 
	 </section> 
	 <section> 
		<title>C'est parti !</title>
		<para>Enfin, presque... il nous reste à faire une dernière petite chose avant de commencer. Créer une page 
		  <ulink url="http://xml.apache.org/cocoon/userdocs/xsp/index.html">XSP</ulink> d'accueil pour notre application.</para>
		<para>Créons un fichier XML avec le contenu (très minimaliste) suivant :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ne pas oublier le namespace XSP -->
<!-- ne pas oublier le namespace SDX -->
<xsp:page language="java" 
	xmlns:xsp="http://apache.org/xsp" 
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:page/>
</xsp:page>
]]></programlisting> 
		<para>Et copions-le dans le répertoire de notre application sous le nom <filename>index.xsp</filename> (nous verrons sous peu pourquoi choisir ce nom plutôt qu'un autre). On a donc :</para>
		<programlisting><![CDATA[
-mon_app
 -conf
  application.xconf
  indexation.xsl
 +xsl  
 index.xsp 
 sitemap.xmap
]]></programlisting> 
		<para>Démarrons maintenant le moteur de servlets et connectons-nous en tant que super-utilisateur (<filename>http://serveur:port/sdx/sdx/admin/loginsu.xsp</filename>) : nous devons en effet <emphasis>ouvrir</emphasis> notre application.</para>
		<para> <emphasis>Truc :</emphasis> on peut également ouvrir une application un créant un fichier du nom du répertoire de l'application dans le répertoire <filename>[TOMCAT_HOME]/sdx/WEB-INF/sdx/applications</filename> et en redémarrant le moteur de sevlets. Son contenu importe peu, aussi le fichier peut-il être vide. Réciproquement, supprimer un fichier de ce type ferme une application.</para>
		<para>Après ouverture, osons enfin cliquer sur le lien qui nous amène vers l'application... (<filename>http://serveur:port/sdx/mon_app</filename>)</para>
		<para> <emphasis role="bold">Patatras !!!</emphasis> </para>
		<para>...SDX nous renvoie une magnifique erreur :</para>
		<para> <literal>org.apache.cocoon.ProcessingException: Exception during processing of file:/C:/tomcat4/webapps/sdx/mon_app/sitemap.xmap: java.io.FileNotFoundException: [TOMCAT_HOME]\sdx\mon_app\sitemap.xmap (Le fichier spécifié est introuvable)</literal> </para>
		<para>Que s'est-il donc passé ? La réponse est dans <filename>sitemap.xmap</filename>. Premier point :</para>
		<programlisting><![CDATA[
<map:match pattern="">
    <map:redirect-to uri="index.xsp"/>
</map:match>
]]></programlisting> 
		<para>Etant donné que nous avons demandé un répertoire plutôt qu'un fichier particulier, Cocoon a cherché à vous rediriger vers une page nommée... <filename>index.xsp</filename>. Second point :</para>
		<programlisting><![CDATA[
<map:match pattern="*.xsp">
    <map:generate type="xsp" src="{1}.xsp"/>
    <map:transform src="xsl/{1}.xsl">
        <map:parameter name="use-request-parameters" value="true"/>
    </map:transform>
    <map:serialize/>
</map:match>
]]></programlisting> 
		<para>... Cocoon a cherché à <emphasis>transformer</emphasis> <filename>index.xsp</filename> avec la XSL <filename>xsl/index.xsl</filename>. Cette XSL n'existant pas (encore), ce qui s'est passé est tout à fait normal !</para>
		<para>Maintenant, si vous cherchez à accéder à <filename>http://serveur:port/sdx/mon_app/index.xsp2sdx</filename>...</para>
		<para>... vous avez <emphasis role="bold">enfin</emphasis> du contenu !</para>
		<programlisting><![CDATA[
 <?xml version="1.0" encoding="ISO-8859-1" ?> 
<sdx:document 
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" 
	xmlns:xsp="http://apache.org/xsp" xml:lang="fr-FR" 
	server="http://localhost:8080/sdx" 
	api-url="http://localhost:8080/sdx/sdx/api-url" 
	uri="http://localhost:8080/sdx/mon_app/index.xsp2sdxX" 
	date="Thu Jan 23 22:57:38 CET 2003">
  <sdx:user anonymous="true" /> 
</sdx:document>			
]]></programlisting> 
		<para>Certes, ce contenu n'est pas très intéressant, mais il est déjà bien plus fourni que votre XSP source puisque vous pouvez constater que SDX est en mesure de donner des informations sur sa configuration et de dire quel est statut de l'utilisateur.</para>
		<para>Comment ce "miracle" a-t-il pu avoir lieu ? Ici encore, la réponse est dans <filename>sitemap.xmap</filename> :</para>
		<programlisting><![CDATA[
<map:match pattern="**.xsp2sdx">
    <map:generate type="xsp" src="{1}.xsp"/>
    <map:transform src="../sdx/resources/xsl/xml.xsl"/>
    <map:serialize type="html"/>
</map:match>
]]></programlisting> 
		<para>On voit que les extensions <filename>xsp2sdx</filename> sont sérialisées en HTML (c'est pour cela que le navigateur est capable d'afficher un résultat) et que la transformation est faite grâce à la précieuse XSL utilitaire mis à notre disposition dans <filename>sdx/sdx/resources/xsl/xml.xsl</filename>. Si votre navigateur est capable d'afficher décemment le XML, vous pouvez utiliser l'extension <filename>xsp2sdxX</filename> qui, elle, sérialise en <literal>text</literal> et que le navigateur sera en principe capable de reconnaître comme étant du XML, forme particulière de <literal>text</literal>.</para>
		<para>Nous voici désormais au coeur de SDX, notre application étant bien configurée, nous allons pouvoir définir sa logique applicative.</para>
	 </section> 
  </section> 
  <section> 
	 <title>Un peu de XSL et de HTML</title>
	 <section> 
		<title>Définition de l'interface utilisateur</title>
		<para>Nous allons utiliser les réglages prédéfinis dans <filename>sitemap.xmap</filename> pour rédiger une XSL à même de transformer la XSP traitée par SDX en HTML utilisable sur un navigateur. Mais au préalable, nous allons définir une XSL commune à toute les pages de notre application ; cette XSL contiendra la logique applicative qui sera partagée entre toutes les pages de l'application. Pour faire simple, nous l'appellerons <filename>common.xsl</filename> et nous la mettrons, naturellement, dans le répertoire <filename>xsl</filename>.</para>
		<para>Cette XSL remplira les fonctions suivantes :</para>
		<itemizedlist>
		  <listitem>
			 <para>générer la structure du document HTML,</para>
		  </listitem>
		  <listitem>
			 <para>afficher une "barre de menus" qui proposera des liens vers les différentes pages de l'application,</para>
		  </listitem>
		  <listitem>
			 <para>appliquer les modèles spécifiques contenus dans les XSL attachées aux XSP,</para>
		  </listitem>
		  <listitem>
			 <para>afficher des informations sur l'utilisateur courant, si tant est que celui-ci soit identifié,</para>
		  </listitem>
		  <listitem>
			 <para>proposer, à fins de débogage, des liens permettant de visionner les différentes étapes de traitement de la XSP.</para>
		  </listitem>
		</itemizedlist>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ne pas oublier le namespace SDX -->
<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" 
  exclude-result-prefixes="xsl sdx">
   <!-- doit-on proposer les liens d'aide au débogage ? -->
   <xsl:variable name="debug" select="true()"/>
	<!-- on récupère les infos concernant l'utilisateur -->
	<xsl:variable name="user" select="/sdx:document/sdx:user"/>
	<!-- le modèle pour la "racine" du contexte SDX -->
	<xsl:template match="/sdx:document">
		<!-- le squelette du document HTML -->
		<html>
			<head>
				<title>Mon application</title>
			</head>
			<body>
				<!-- la barre de menus -->
				<xsl:call-template name="menubar"/>
				<!-- les modèles spécifiques à chaque XSP -->
				<xsl:apply-templates/>
				<!-- le bas de page -->
				<xsl:call-template name="footer"/>
			</body>
		</html>
	</xsl:template>
	<xsl:template name="menubar">
	   <!-- le contexte de notre application -->
	   <xsl:variable name="app_context">/mon_app/</xsl:variable>
		<!-- on récupère le contexte SDX -->
		<!-- http://server:port/sdx par exemple -->
		<xsl:variable name="SDX_context" select="/sdx:document/@server"/>
		<!-- on récupère l'URI de la page courante -->
		<!-- http://server:port/sdx/mon_app/index.xsp par exemple -->
		<xsl:variable name="page_URI" select="/sdx:document/@uri"/>
		<!-- on en déduit le contexte de la page dans SDX -->
		<!-- /mon_app/index.xsp par exemple -->
		<xsl:variable name="page_SDX" select="substring-after($page_URI,$SDX_context)"/>
		<!-- on en déduit le contexte de la page dans l'application -->
		<!-- index.xsp par exemple -->
		<xsl:variable name="page_name" select="substring-after($page_URI,$app_context)"/>
		<!-- 
		notre application insèrera un élément <admin_page/>
		pour les pages nécessitant des privilèges d'administrateur,
		s'il est detecté, on est dans une telle page
		-->
		<xsl:variable name="admin_page" select="boolean(/sdx:document/admin_page)"/>
		<table align="center" cellpadding="10">
			<tr>
				<!--
				si on n'est pas dans la page d'index,
				propose un lien vers elle
				-->
				<xsl:if test="not($page_name = 'index.xsp')">
					<td>
						<a href="index.xsp">Index</a>
					</td>
				</xsl:if>
				<!-- 
				si on n'est pas dans la page d'interrogation,
				propose un lien vers elle
				 -->
				<xsl:if test="not($page_name = 'query.xsp')">
					<td>
						<a href="query.xsp">Interrogation</a>	
					</td>
				</xsl:if>
				<!--
				si on n'est pas dans la page d'identification,
				propose un lien vers elle
				 -->
				<xsl:if test="not($page_name = 'login.xsp')">
					<td>
						<a href="login.xsp">Identification</a>
					</td>
				</xsl:if>
				<!--
				si on est identifié hors d'une page d'administration,
				propose une déconnection : on reste sur la même page
				 -->
				<xsl:if test="not($admin_page) and not($user/@anonymous)">
					<td>
						<!-- 
						truc SDX : 
						il suffit de passer un paramètre logout non vide 
						-->
						<a href="{$page_URI}?logout=yes">Fin d'identification</a>
					</td>
				</xsl:if>
				<!-- 
				si on n'est pas sur la page d'ajout de documents
				et si on est administrateur,
				propose un lien vers elle
				-->
				<xsl:if test="not($page_name = 'query.xsp') and $user/@admin='true'">
					<td>
						<a href="upload.xsp">Ajouter des documents</a>
					</td>
				</xsl:if>
			</tr>
		</table>
		<hr/>
		<br/>
	</xsl:template>
	<xsl:template name="footer">
		<br/>
		<hr/>
		<xsl:call-template name="userinfo"/>
		<xsl:if test="$debug">
			<xsl:call-template name="views"/>
		</xsl:if>
	</xsl:template>
	<xsl:template name="userinfo">
		<!-- rien à faire si l'utilisateur est anonyme -->
		<xsl:if test="not($user/@anonymous)">
			<!-- on reconstitue le nom de l'utilisateur -->
			<xsl:variable name="fullname">
				<xsl:if test="$user/@firstname or $user/@lastname">
					(
					<xsl:if test="$user/@firstname">
						<xsl:value-of select="$user/@firstname"/>&#160;
					</xsl:if>
					<xsl:if test="$user/@lastname">
						<xsl:value-of select="$user/@lastname"/>&#160;
					</xsl:if>
					),
				</xsl:if>
			</xsl:variable>
			<!-- on détermine son statut -->
			<xsl:variable name="user_status">
				<xsl:choose>
					<xsl:when test="$user/@superuser='true'">
						le super-utilisateur
					</xsl:when>
					<xsl:when test="$user/@admin='true'">
						un administrateur
					</xsl:when>
					<xsl:when test="$user/@app">
						un utilisateur
					</xsl:when>
					<!-- au cas où on aurait oublié quelque chose... -->
					<xsl:otherwise>bug !</xsl:otherwise>
				</xsl:choose>
			</xsl:variable>
			<!-- et on sort l'info -->
			<div class="user">	
				Vous <xsl:value-of select="$fullname"/> êtes identifié sous le code 
				<span class="user_id"><xsl:value-of select="$user/@id"/></span>. 
				Vous êtes <xsl:value-of select="$user_status"/> de l'application&#160;
				<span class="app_id"><xsl:value-of select="$application"/></span>.
			</div>
		</xsl:if>
	</xsl:template>
	<xsl:template name="views">
		<table>
			<tr>
				<td>Les étapes de cette page : </td>
				<td>1) <a href="{/sdx:document/@uri}2xsp{/sdx:document/@query}">XSP</a>
				</td>
				<td>2) <a href="{/sdx:document/@uri}2sdx{/sdx:document/@query}">SDX</a>
				</td>
				<td>3) <a href="{/sdx:document/@uri}2htm{/sdx:document/@query}">HTM</a>
				</td>
			</tr>
		</table>
	</xsl:template>
	<!-- 
	un template qu'on pourra utiliser
	si un utilisateur cherche à faire des opérations
	pour lesquelles il n'a pas les privilèges suffisants
	-->
	<xsl:template match="nosuchprivileges">
		<div class="privileges">
		Vous n'avez pas les privilèges suffisants pour effectuer cette opération.
		</div>
	</xsl:template>
</xsl:stylesheet>
]]></programlisting> 
		<para>On le voit, l'essentiel de l'opération consiste à se procurer les différents attributs et sous-éléments de <sgmltag>&lt;sdx:document&gt;</sgmltag> pour définir la logique applicative en fonction de leurs valeurs. En attendant une documentation plus complète, une idée de l'architecture du contexte SDX est donnée dans un 
		  <ulink url="../../samples/sdx-document.xml">document exemple</ulink>. L'objectif des étapes suivantes consistera à s'approprier ce contexte.</para>
		<para>Retouchons maintenant très légèrement notre <filename>index.xsp</filename> :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ne pas oublier le namespace XSP -->
<!-- ne pas oublier le namespace SDX -->
<xsp:page language="java" 
	xmlns:xsp="http://apache.org/xsp" 
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx">
	<sdx:page>
		<!-- 
		si un paramètre logout est présent,
		on se déconnecte
		-->
		<sdx:logout/>			
		<!-- 
		un élément personnalisé
		qui n'est pas dans le namespace SDX
		-->
		<myindex/>
	</sdx:page>
</xsp:page>]]></programlisting> 
		<para>Nous devons maintenant rédiger la XSL chargée de traiter le code, ô combien spécifique, de <filename>index.xsp</filename>. Rappelons que selon <filename>sitemap.xmap</filename>, elle doit s'appeler <filename>index.xsl</filename> et se trouver dans le répertoire <filename>xsl</filename>. Nous allons faire très simple :</para>
		<programlisting><![CDATA[
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- ne pas oublier le namespace SDX -->
<xsl:stylesheet version="1.0" 
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
	xmlns:sdx="http://www.culture.gouv.fr/ns/sdx/sdx" 
	exclude-result-prefixes="sdx">
<!-- on insère la XSL commune... -->
	<xsl:include href="common.xsl"/>	
<!-- puis un modèle spécifique pour notre contenu -->	
	<xsl:template match="/sdx:document/myindex">
		<!-- du code HTML -->
		<h1>Mon application</h1>
		<p>Voici ma première application SDX.</p>
		<p>Elle a une barre de menus, mais la plupart des pages sont en construction.</p>
		<p>Ne pas hésiter à utiliser les liens en bas de page pour le débogage&#160;!</p>
	</xsl:template>	
</xsl:stylesheet>
]]></programlisting> 
		<para>Nous pouvons désormais accéder à l'URL <filename>http://serveur:port/sdx/mon_app/index.xsp</filename> et... voir le résultat.</para>
		<para>Comme prévu, nous avons bien une barre de menus (avec des liens qui ne sont pas encore actifs), notre contenu et nos liens d'aide au débogage qui nous permettent :</para>
		<itemizedlist>
		  <listitem>
			 <para>d'accéder au code source de la XSP,</para>
		  </listitem>
		  <listitem>
			 <para>d'accéder au contexte SDX, c'est à dire à la façon dont SDX a interprété la XSP. En plus du traitement lui-même, SDX greffe de nombreuses informations destinées à aider le développeur d'application. A lui de décider s'il veut utiliser cette information et comment il veut le faire...</para>
		  </listitem>
		  <listitem>
			 <para>d'accéder au code source du HTML sérialisé par Cocoon.</para>
		  </listitem>
		</itemizedlist>
		<para>En revanche, aucune information sur l'utilisateur : c'est normal, nous avons volontairement choisi de masquer l'information quand l'utilisateur est anonyme. C'est aussi pour cela que nous n'avons pas de lien vers la page d'ajouts de documents.</para>
	 </section> 
  </section> 
  <section> 
	 <title>Plus loin avec les XSP</title>
	 <para/> 
  </section> 
  <section> 
	 <title>Pistes pour des configurations personnalisées</title>
	 <para></para>
  </section> 

</webpage> 
